【发布时间】:2019-08-08 04:20:29
【问题描述】:
问题
编辑:正如 cmets 中指出的那样,我在 pthread_cond_wait 上犯了一个错误,导致它永远不会退出线程。
我正在使用 C 语言进行多线程分配,我需要使用多个线程通过 shearsort 对 4x4 数组进行排序,但我无法做到这一点因为每当我使用我搞砸了我的pthread_join 时,应用程序永远不会结束,也永远不会加入。应用程序只是停留在原处,直到我控制 C 来结束它。pthread_cond_wait,这意味着某些线程将永远不会继续。
我想我是在问我应该如何使用pthread_wait_cond,因为当我在 if/else 语句的两边都有 pthread_wait_cond 时,它不会输出任何东西,只会卡住。
另外,这现在是主要问题的一部分,但我看到很多人在 for 循环中启动 pthread,但是当我尝试传递给函数的 i 变量似乎是随机设置的,有时是正确的每个线程都有自己的编号,但有时线程会使用相同的编号创建。我是否需要使用某种互斥锁来确保pthread_create 自动发生,我应该怎么做?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sched.h>
#include <fcntl.h>
#include <pthread.h>
#define N 4
void intSwap(int *a, int *b);
void *shearSort(void *rowCol);
pthread_cond_t sort0 = PTHREAD_COND_INITIALIZER;
pthread_cond_t sort1 = PTHREAD_COND_INITIALIZER;
pthread_cond_t sort2 = PTHREAD_COND_INITIALIZER;
pthread_cond_t sort3 = PTHREAD_COND_INITIALIZER;
pthread_cond_t writeArray = PTHREAD_COND_INITIALIZER;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
int array[N][N];
pthread_t thread[N];
void *shearSort(void *rowCol) {
int x = 0, y = 0;
printf("rowCol = %d", ((int)*(int*)rowCol));
pthread_mutex_lock(&lock);
if (((int)*(int*)rowCol)%2 == 0) {
for(x = 0; x < N-1; x++) {
for (y = 0; y < N-x-1; y++) {
//pthread_cond_wait(&writeArray, &lock);
if (array[((int)*(int*)rowCol)][y] > array[((int)*(int*)rowCol)][y+1]) {
printf("rowCol = %d, i = %d, j = %d Swapping %d & %d\n", ((int)*(int*)rowCol), x, y, array[((int)*(int*)rowCol)][y], array[((int)*(int*)rowCol)][y+1]);
intSwap(&array[((int)*(int*)rowCol)][y], &array[((int)*(int*)rowCol)][y+1]);
}
//pthread_cond_signal(&writeArray);
}
}
}
else {
for(x = 0; x < N-1; x++) {
for (y = 0; y < N-x-1; y++) {
//pthread_cond_wait(&writeArray, &lock);
if (array[((int)*(int*)rowCol)][y] < array[((int)*(int*)rowCol)][y+1]) {
printf("rowCol = %d, i = %d, j = %d Swapping %d & %d\n", ((int)*(int*)rowCol), x, y, array[((int)*(int*)rowCol)][y], array[((int)*(int*)rowCol)][y+1]);
intSwap(&array[((int)*(int*)rowCol)][y], &array[((int)*(int*)rowCol)][y+1]);
}
//pthread_cond_signal(&writeArray);
}
}
}
pthread_mutex_unlock(&lock);
if(((int)*(int*)rowCol) == 1) {
//pthread_join(thread[0], NULL);
}
if(((int)*(int*)rowCol) == 2) {
//pthread_join(thread[0], NULL);
//pthread_join(thread[1], NULL);
}
if(((int)*(int*)rowCol) == 3) {
//pthread_join(thread[0], NULL);
//pthread_join(thread[1], NULL);
//pthread_join(thread[2], NULL);
}
pthread_exit(NULL);
}
void intSwap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
int main () {
FILE *input;
int i = 0, j = 0;
input = fopen("input.txt" , "r");
if (input != NULL) {
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) {
fscanf(input, "%d, ", &array[i][j]);
printf("%d, ", array[i][j]);
}
printf("\n");
}
printf("\n");
}
else {
perror( "There's a problem with the input.txt file, it doesn't seem to be there.");
exit( EXIT_FAILURE );
}
// for (i = 0; i < N; i++) {
// pthread_create(&thread[i], NULL, shearSort, (void *)&i);
// }
// for (i = 0; i < N; i++) {
// pthread_join(thread[i], NULL);
// }
int num0 = 0, num1 = 1, num2 = 2, num3 = 3;
pthread_create(&thread[0], NULL, shearSort, (void *)&num0);
pthread_create(&thread[1], NULL, shearSort, (void *)&num1);
pthread_create(&thread[2], NULL, shearSort, (void *)&num2);
pthread_create(&thread[3], NULL, shearSort, (void *)&num3);
pthread_join(thread[num0], NULL);
pthread_join(thread[1], NULL);
pthread_join(thread[2], NULL);
pthread_join(thread[3], NULL);
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) {
printf("%d, ", array[i][j]);
}
printf("\n");
}
return 0
}
当我在 else 中在 pthread_cond_wait 上运行上面没有 cmets 的代码时,我从命令行得到了这个输出,然后它就停止了。
5, 3, 9, 10,
2, -3, 11, 8,
20, 17, 19, 30,
24, 21, -2, 16,
rowCol = 0rowCol = 0, i = 0, j = 0 Swapping 5 & 3
rowCol = 1rowCol = 2rowCol = 2, i = 0, j = 0 Swapping 20 & 17
rowCol = 2, i = 0, j = 1 Swapping 20 & 19
^C
现在,当我按原样运行代码时,我会得到以下输出:
5, 3, 9, 10,
2, -3, 11, 8,
20, 17, 19, 30,
24, 21, -2, 16,
rowCol = 0rowCol = 0, i = 0, j = 0 Swapping 5 & 3
rowCol = 1rowCol = 1, i = 0, j = 1 Swapping -3 & 11
rowCol = 1, i = 0, j = 2 Swapping -3 & 8
rowCol = 1, i = 1, j = 0 Swapping 2 & 11
rowCol = 1, i = 1, j = 1 Swapping 2 & 8
rowCol = 2rowCol = 2, i = 0, j = 0 Swapping 20 & 17
rowCol = 2, i = 0, j = 1 Swapping 20 & 19
rowCol = 3rowCol = 3, i = 0, j = 2 Swapping -2 & 16
3, 5, 9, 10,
11, 8, 2, -3,
17, 19, 20, 30,
24, 21, 16, -2,
【问题讨论】:
-
为什么你对第一个索引使用
num0,而对其他索引进行硬编码?而且根本不需要num0到num3变量,而是使用循环。 -
哦,对不起,我这样做只是为了看看是否有什么不同,然后我忘了把它改回来。至于当我尝试使用循环时,我遇到了一个问题,有时两个不同的线程会从 i 接收相同的输入值,这也是我的问题的一部分。
-
OT:不管 Visual Studio 允许什么,该函数只有两个有效签名:
main()它们是:int main( void )和int main( int argc, char *argv[] )请注意,它们都有一个返回类型int,不是void -
在函数中:
main()这个语句:return;应该是:return 0; -
我没有使用Visual Studio,我用Notepad++编写并在我学校的黄铁矿服务器上编译,但谢谢你指出,我把它改回int,我不记得了为什么我首先将其切换为 void 哈哈
标签: c multithreading thread-safety pthreads