感谢大家的精彩回答!有很多关于使用内存屏障等的讨论 - 所以我想我会发布一个正确显示它们用于此的答案。
#define NUM_THREADS 5
unsigned int thread_count;
void *threadfunc(void *arg) {
printf("Thread %p running\n",arg);
sleep(3);
printf("Thread %p exiting\n",arg);
__sync_fetch_and_sub(&thread_count,1);
return 0L;
}
int main() {
int i;
pthread_t thread[NUM_THREADS];
thread_count=NUM_THREADS;
for (i=0;i<NUM_THREADS;i++) {
pthread_create(&thread[i],0L,threadfunc,&thread[i]);
}
do {
__sync_synchronize();
} while (thread_count);
printf("All threads done\n");
}
请注意,__sync 宏是“非标准”GCC 内部宏。 LLVM 也支持这些 - 但如果您使用其他编译器,您可能需要做一些不同的事情。
要注意的另一件大事是:为什么要烧掉整个内核,或者浪费 CPU 的“一半”在一个紧密的轮询循环中等待其他人完成 - 当你可以轻松地让它工作时?以下 mod 使用初始线程运行其中一个工作人员,然后等待其他工作人员完成:
thread_count=NUM_THREADS;
for (i=1;i<NUM_THREADS;i++) {
pthread_create(&thread[i],0L,threadfunc,&thread[i]);
}
threadfunc(&thread[0]);
do {
__sync_synchronize();
} while (thread_count);
printf("All threads done\n");
}
注意我们从“1”而不是“0”开始创建线程,然后直接运行“thread 0”内联,等待所有线程完成后完成。我们将 &thread[0] 传递给它以保持一致性(即使它在这里毫无意义),但实际上您可能会传递自己的变量/上下文。