我遇到了线程问题。我试图在二维数组中找到主对角线的最大元素。第一个pthread会做它的事情并找到最大元素。但是,当第二个和第四个等阵列"加入党#34;他们不会进入第二次。我的功能如下:
void* findMax() {
//int t = 1;
//*arr.times = 0;
for (*arr.countI = 0; *arr.countI < *arr.l; (*arr.countI)++) {
for (*arr.countJ = 0; *arr.countJ < *arr.l; (*arr.countJ)++) {
printf("%d ", arr.a[*arr.countI][*arr.countJ]);
if (*arr.l - *arr.countJ == 1)
printf("\n");
}
}
*arr.countI = 0;
*arr.countJ = 0;
while (*arr.countI != *arr.l) {
while (*arr.countJ != *arr.l) {
if (*arr.countI == *arr.countJ) {
if (abs(arr.a[*arr.countI][*arr.countJ]) > *arr.max)
*arr.max = abs(arr.a[*arr.countI][*arr.countJ]);
}
++(*arr.countJ);
}
++(*arr.countI);
/*if (++(*arr.times) == 1) {
*arr.times = 0;
break;
}*/
}
printf("max = %d\n", *arr.max);
}
所以如果我输入这个数组
4 1 1
1 6 1
1 1 3
max将等于4,当然不是正确的。
arr
是一个结构(全局),拥有我需要的一切; arr.a
是数组。
在过去的几天里,我已经搞砸了很多但没有运气......
答案 0 :(得分:1)
正如之前在评论中提到的,你没有相互排斥,所以你的线程都忙于操纵全局数组的元素而不考虑其他线程在做什么。
所有这些
*arr.countI
等引用都很难看。相互排除在哪里确保没有线程正在修改arr
内的任何内容,而另一个线程也在修改它?例如,您有*arr.countI = 0;
,但没有可见的互斥。您有*arr.max = abs(arr.a[*arr.countI][*arr.countJ]);
且没有相互排斥。您有++(*arr.countJ);
且没有相互排斥。这些线程都没有关于发生了什么的第一个线索。也许你很幸运,*arr.countI == *arr.l
所以他们没有进入循环。但是你没有并发控制,所以一切都是猜测。我认为您应该停止使用全局数据中的
countI
和countJ
,以及大多数时间arr.max
。应该用每线程局部变量(int i; int j; int max;
)替换它们。如果您沿着主对角线向下扫描,则不需要嵌套循环 - 您可以简单地沿着对角线向下走。对于一项非常简单的工作,您的代码非常复杂。您仍需要一个互斥锁才能可靠地设置*arr.max
。arr.a
和*arr.l
是&#39;好的&#39; (但为什么*arr.l
是一个指针?)因为你没有修改它们。您承诺返回void *
并且不返回任何内容。说谎你的编译器是一个坏主意™。
如果您的线程将任何内容存储到您的全局结构中(arr
),则需要确保存在互斥。我假设你有或添加一个成员mtx
,它是一个指向pthread_mutex_t
的指针,它在调用线程函数之前被初始化。我还假设您的findMax()
函数是从pthread_create()
调用的(并作为函数指针传递给它)。
您可以使用更简单的代码来完成任务,例如:
void *findMax(void *arg)
{
assert(arg == 0);
for (int i = 0; i < *arr.l; i++) {
for (int j = 0; j < *arr.l; j++) {
printf("%d ", arr.a[i][j]);
}
printf("\n");
}
int max = abs(arr.a[0][0]);
for (int i = 1; i < *arr.l; i++)
{
int absval = abs(arr.a[i][i]);
if (absval > max)
max = absval;
}
if (pthread_mutex_lock(arr.mtx) == 0)
{
*arr.max = max;
pthread_mutex_unlock(arr.mtx);
}
printf("max = %d\n", *arr.max);
return 0;
}
警告:未编译的代码!