我正在尝试自学pthreads线程。我有以下源代码,它可以正确编译和运行:
#include <stdio.h>
#include <pthread.h>
#define PTHREAD_COUNT 10
#define FREQ 5
void *thread_function(void *arg) {
int *incoming = (int *)arg;
int freqIdx;
for (freqIdx = 0; freqIdx < FREQ; freqIdx++)
fprintf(stdout, "Hello, world (thread %d)\n", *incoming);
return NULL;
}
int main(int argc, char **argv) {
pthread_t thread_IDs[PTHREAD_COUNT];
void *exit_status;
int threadIdx;
for (threadIdx = 0; threadIdx < PTHREAD_COUNT; threadIdx++) {
pthread_create(&thread_IDs[threadIdx], NULL, thread_function, &threadIdx);
pthread_join(thread_IDs[threadIdx], &exit_status);
}
return 0;
}
我得到以下结果:
Hello, world (thread 0)
Hello, world (thread 0)
Hello, world (thread 0)
Hello, world (thread 0)
Hello, world (thread 0)
Hello, world (thread 1)
...
Hello, world (thread 9)
如果我在一个循环中pthread_create
一个pthread_t
类型的数组,然后在一个单独的循环中pthread_join
,那么事情就会失败:
#include <stdio.h>
#include <pthread.h>
#define PTHREAD_COUNT 10
#define FREQ 5
void *thread_function(void *arg) {
int *incoming = (int *)arg;
int freqIdx;
for (freqIdx = 0; freqIdx < FREQ; freqIdx++)
fprintf(stdout, "Hello, world (thread %d)\n", *incoming);
return NULL;
}
int main(int argc, char **argv) {
pthread_t thread_IDs[PTHREAD_COUNT];
void *exit_status;
int threadIdx;
/* here I split the thread _create and _join steps into separate loops */
for (threadIdx = 0; threadIdx < PTHREAD_COUNT; threadIdx++)
pthread_create(&thread_IDs[threadIdx], NULL, thread_function, &threadIdx);
for (threadIdx = 0; threadIdx < PTHREAD_COUNT; threadIdx++)
pthread_join(thread_IDs[threadIdx], &exit_status);
return 0;
}
这个输出是非常错误的。我没有从每个线程中获取五个fprintf
语句,而是从线程0和线程2中获得一个或两个,以及从线程0获得大约20到25个Hello, world
语句。
为什么这会失败?
答案 0 :(得分:2)
我看到的一个问题是你给它一个地址变量threadIdx的地址。在循环中修改它时,线程看到的值也会更改。所以threadIdx值不正确。
在第二个循环中,你再次将threadIdx设置为0并等待线程完成,这解释了为什么你会看到很多人打印出线程0而不是。
你可以简单地传递threadIdx,然后将void * args解释为int(因为sizeof(int)&lt; = sizeof(void *)并且通常在大多数机器上得到保证)并且你应该得到正确的输出。< / p>
答案 1 :(得分:1)
将指向同一threadIdx
变量的指针传递给所有线程。
答案 2 :(得分:1)
正如其他人所说,你的问题是在所有线程之间共享一个threadIdx
变量。解决此问题的一种方法是为每个线程创建一个变量:
int threadIdx;
int indexes[PTHREAD_COUNT];
for (threadIdx = 0; threadIdx < PTHREAD_COUNT; threadIdx++) {
indexes[threadIdx] = threadIdx;
pthread_create(&thread_IDs[threadIdx], NULL, thread_function, &indexes[threadIdx]);
}