我目前正在尝试学习C语言中的多线程。但是我得到了非常意外的结果,让我感到难过。在这个程序中,我试图通过使用线程来填充矩阵。我正在创建1024个线程,将i值传递给函数。然后我继续使用它。
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define SIZE 1024
static double a[SIZE][SIZE];
static double b[SIZE][SIZE];
static double c[SIZE][SIZE];
void*
init_matrix(void* msg)
{
int j;
int num = *((int*) msg);
printf("%d\n", num);
for (j = 0; j < SIZE; j++) {
a[num][j] = drand48();
b[num][j] = drand48();
}
pthread_exit(NULL);
}
int
main(int argc, char **argv)
{
//Init threads
pthread_t p_initThreads[SIZE];
int i,j;
for(i = 0; i< SIZE; i++)
{
pthread_create(&p_initThreads[i], NULL, init_matrix, (void*)&i);
}
for(j = 0; j<SIZE; j++)
{
pthread_join(p_initThreads[j], NULL);
}
}
prinf的预期结果将是; 1-2-3-4-5-6-7-8-9-10。随着可能 因为它在线程中而导致它的结果。但是我的电脑上的结果是这样的;
1-2-2-4-5-7-24-25-25-25-25-25-25-25-25-25-25-25-25-25-25-25-25-25-25-26-35-36-36-37-37-37-37-37-37-37-37-38-39-40
通过评论;
for (j = 0; j < SIZE; j++) {
a[num][j] = drand48();
b[num][j] = drand48();
}
我得到了我想要的结果。这是为什么?它不应该对num做任何事情!
答案 0 :(得分:1)
您正在传递i
的地址作为线程的输入参数。如果你传递i
的值,你会得到1-2-3-4-5 -...但是当你传递地址时,完全有可能在执行printf
行之前,主线程已经递增i
。 printf
显示i
的当前值,而不是创建线程时的值。
答案 1 :(得分:0)
你所拥有的是race condition,其中多个线程访问相同的内存位置(变量i
),因为你将i
的地址传递给所有线程。
您真正想要做的是传递i
的值。使用:
pthread_create()
pthread_create(&p_initThreads[i], NULL, init_matrix, (void*)i);
并将值读为:
int num = (int) msg;
代替:int num = *((int*) msg);
您还应该检查pthread_create()
是否为失败返回非零值。如果是这样,那么您将无法获得预期的结果。