我使用pthread_create
创建了许多线程,在每个线程中,我使用线程id作为输入来生成名称字符串thread_<id>
,这是有问题的代码:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>
#define THREAD_NUM 40
void *common_function(void *arg);
int main (void)
{
int res;
unsigned int i;
pthread_t t[THREAD_NUM];
memset(t, 0x0, sizeof(t));
for(i = 0; i < THREAD_NUM; i++)
{
/* pass info */
res = pthread_create(&(t[i]), NULL, common_function, (void *)&i);
if(res !=0)
{
printf("thread: %d create fail\n", i);
return -1;
}
}
for(i=0; i<THREAD_NUM; i++)
{
pthread_join(t[i], NULL);
}
return 0;
}
void *common_function(void *arg)
{
unsigned int p;
#ifdef WRITE_FILE
FILE *fd;
char name[64];
#endif
p = *(unsigned int *)arg;
#ifdef WRITE_FILE
memset(name, 0x0, sizeof(name));
sprintf(name, "thread_%02d", p);
fd = fopen(name, "w");
if(fd < 0 )
{
printf("create: %s fail\n", name);
pthread_exit((void *)&p);
}
#endif
#ifdef WRITE_FILE
fprintf(fd, "%02d\n", p);
#else
printf("thread: %02d\n",p);
#endif
usleep(1);
#ifdef WRITE_FILE
fclose(fd);
#endif
pthread_exit((void *)&p);
}
我编译了代码使用(我没有看到任何警告):
gcc -Wall -g -pthread -D_REENTRANT -DWRITE_FILE ./test_thread_problem.c
输出是:
-rw-rw-r-- 1 haochen haochen 3 3月 13 08:56 thread_02
-rw-rw-r-- 1 haochen haochen 3 3月 13 08:56 thread_03
-rw-rw-r-- 1 haochen haochen 3 3月 13 08:56 thread_04
-rw-rw-r-- 1 haochen haochen 3 3月 13 08:56 thread_05
-rw-rw-r-- 1 haochen haochen 3 3月 13 08:56 thread_06
-rw-rw-r-- 1 haochen haochen 3 3月 13 08:56 thread_07
-rw-rw-r-- 1 haochen haochen 3 3月 13 08:56 thread_08
-rw-rw-r-- 1 haochen haochen 3 3月 13 08:56 thread_09
-rw-rw-r-- 1 haochen haochen 3 3月 13 08:56 thread_11
-rw-rw-r-- 1 haochen haochen 3 3月 13 08:56 thread_12
-rw-rw-r-- 1 haochen haochen 3 3月 13 08:56 thread_13
-rw-rw-r-- 1 haochen haochen 3 3月 13 08:56 thread_14
-rw-rw-r-- 1 haochen haochen 3 3月 13 08:56 thread_16
-rw-rw-r-- 1 haochen haochen 3 3月 13 08:56 thread_17
-rw-rw-r-- 1 haochen haochen 3 3月 13 08:56 thread_18
-rw-rw-r-- 1 haochen haochen 3 3月 13 08:56 thread_19
-rw-rw-r-- 1 haochen haochen 3 3月 13 08:56 thread_20
-rw-rw-r-- 1 haochen haochen 3 3月 13 08:56 thread_21
-rw-rw-r-- 1 haochen haochen 3 3月 13 08:56 thread_22
-rw-rw-r-- 1 haochen haochen 3 3月 13 08:56 thread_23
-rw-rw-r-- 1 haochen haochen 3 3月 13 08:56 thread_24
-rw-rw-r-- 1 haochen haochen 3 3月 13 08:56 thread_25
-rw-rw-r-- 1 haochen haochen 3 3月 13 08:56 thread_26
-rw-rw-r-- 1 haochen haochen 3 3月 13 08:56 thread_28
-rw-rw-r-- 1 haochen haochen 3 3月 13 08:56 thread_29
-rw-rw-r-- 1 haochen haochen 3 3月 13 08:56 thread_31
-rw-rw-r-- 1 haochen haochen 3 3月 13 08:56 thread_32
-rw-rw-r-- 1 haochen haochen 3 3月 13 08:56 thread_33
-rw-rw-r-- 1 haochen haochen 3 3月 13 08:56 thread_34
-rw-rw-r-- 1 haochen haochen 3 3月 13 08:56 thread_35
-rw-rw-r-- 1 haochen haochen 3 3月 13 08:56 thread_36
-rw-rw-r-- 1 haochen haochen 3 3月 13 08:56 thread_37
-rw-rw-r-- 1 haochen haochen 3 3月 13 08:56 thread_38
-rw-rw-r-- 1 haochen haochen 3 3月 13 08:56 thread_39
您可能会发现错过了一些文件,但在致电pthread_create
或fopen
后,它永远不会打印出失败信息。我更改为仅在没有创建文件的情况下打印(没有-DWRITE_FILE
选项),也可以看到问题:
./a.out
thread: 03
thread: 07
thread: 03
thread: 04
thread: 04
thread: 05
thread: 06
thread: 15
thread: 19
thread: 19
thread: 19
thread: 19
thread: 19
thread: 19
thread: 20
thread: 20
thread: 20
thread: 20
thread: 20
thread: 20
thread: 21
thread: 22
thread: 23
thread: 27
thread: 29
thread: 29
thread: 31
thread: 37
thread: 38
thread: 38
thread: 38
thread: 38
thread: 38
thread: 38
thread: 38
thread: 39
thread: 04
thread: 05
thread: 18
thread: 18
有什么问题?
答案 0 :(得分:1)
您为所有线程传递相同的i
参数。
res = pthread_create(&(t[i]), NULL, common_function, (void *)&i);
^^
这导致竞争条件,因为主线程修改i
,而所有其他线程从i
读取。我建议你为每个线程使用不同的变量。
unsigned int tid[THREAD_NUM];
...
for(i = 0; i < THREAD_NUM; i++) {
/* pass info */
tid[i] = i;
res = pthread_create(&(t[i]), NULL, common_function, (void *)&tid[i]);
...