C - pthread_join() 挂起(有时)
C - pthread_join() hangs (sometimes)
各位程序员大家好,
我想用 pthread 在 C 中编写一个简单的多线程程序,但是 pthread_join 似乎挂起。
似乎并非总是如此,有时一切都很好 运行,下次它不会再次挂起,通常是在第一个线程上。
我已经将代码最小化到最低限度,这样我就可以排除其他问题。当然,在完整代码中,线程进行了一些计算。但是即使使用这种非常精简的代码,问题仍然存在。并且在不止一台机器上,具有不同的 OS'es.
strace 告诉我悬挂与 FUTEX_WAIT 有关,完整的最后一行:
write(1, "Joining Thread 0...\n", 20Joining Thread 0...
) = 20
futex(0x7fff61718a20, FUTEX_WAIT, 1634835878, NULL
我尝试用 gdb 调试它,但我糟糕的调试效果非常有限,尤其是对于多线程程序。
我还尝试使用不同的 C 标准(C99 和 Ansi)和两个 pthread 参数(-lpthread、-pthread)对其进行编译,但问题仍然存在。
(简化)代码 monte2.c:
#include <stdio.h>
#include <pthread.h>
void *monte(struct MonteArgs *args) {
pthread_exit(NULL);
}
int main(int argc, char **argv) {
int numThreads, numSamples;
int i;
if (argc != 3) {
printf("Usage: monte threads samples\n");
exit(1);
}
numThreads = atoi(argv[1]);
pthread_t threads[numThreads];
numSamples = atoi(argv[2]);
for (i=0; i<numThreads; i++) {
if (pthread_create(&threads[i], NULL, monte, NULL)) {
printf("Error Creating Thread %d!\n", i);
return 1;
}
}
for (i=0; i<numThreads; i++){
printf("Joining Thread %d...\n", i);
pthread_join(&threads[i], NULL);
}
printf("End!\n");
fflush(stdout);
return(0);
}
我用
编译
gcc monte2.c -lpthread -o monte
和运行与
./monte2 3 100
其中第一个参数是线程数,第二个参数对于简化代码实际上不需要。
自从我完成多线程 C 以来已经有一段时间了,但你不应该忽略编译器警告:-)。用 -Wall
编译。
您应该会看到这样的警告:
note: expected 'pthread_t' but argument is of type 'pthread_t *'
int WINPTHREAD_API pthread_join(pthread_t t, void **res);
当您应该超过 pthread_t
时,您却超过了 pthread_t*
。
参考 pthread_join
文档:http://man7.org/linux/man-pages/man3/pthread_join.3.html
各位程序员大家好,
我想用 pthread 在 C 中编写一个简单的多线程程序,但是 pthread_join 似乎挂起。 似乎并非总是如此,有时一切都很好 运行,下次它不会再次挂起,通常是在第一个线程上。
我已经将代码最小化到最低限度,这样我就可以排除其他问题。当然,在完整代码中,线程进行了一些计算。但是即使使用这种非常精简的代码,问题仍然存在。并且在不止一台机器上,具有不同的 OS'es.
strace 告诉我悬挂与 FUTEX_WAIT 有关,完整的最后一行:
write(1, "Joining Thread 0...\n", 20Joining Thread 0...
) = 20
futex(0x7fff61718a20, FUTEX_WAIT, 1634835878, NULL
我尝试用 gdb 调试它,但我糟糕的调试效果非常有限,尤其是对于多线程程序。 我还尝试使用不同的 C 标准(C99 和 Ansi)和两个 pthread 参数(-lpthread、-pthread)对其进行编译,但问题仍然存在。
(简化)代码 monte2.c:
#include <stdio.h>
#include <pthread.h>
void *monte(struct MonteArgs *args) {
pthread_exit(NULL);
}
int main(int argc, char **argv) {
int numThreads, numSamples;
int i;
if (argc != 3) {
printf("Usage: monte threads samples\n");
exit(1);
}
numThreads = atoi(argv[1]);
pthread_t threads[numThreads];
numSamples = atoi(argv[2]);
for (i=0; i<numThreads; i++) {
if (pthread_create(&threads[i], NULL, monte, NULL)) {
printf("Error Creating Thread %d!\n", i);
return 1;
}
}
for (i=0; i<numThreads; i++){
printf("Joining Thread %d...\n", i);
pthread_join(&threads[i], NULL);
}
printf("End!\n");
fflush(stdout);
return(0);
}
我用
编译gcc monte2.c -lpthread -o monte
和运行与
./monte2 3 100
其中第一个参数是线程数,第二个参数对于简化代码实际上不需要。
自从我完成多线程 C 以来已经有一段时间了,但你不应该忽略编译器警告:-)。用 -Wall
编译。
您应该会看到这样的警告:
note: expected 'pthread_t' but argument is of type 'pthread_t *'
int WINPTHREAD_API pthread_join(pthread_t t, void **res);
当您应该超过 pthread_t
时,您却超过了 pthread_t*
。
参考 pthread_join
文档:http://man7.org/linux/man-pages/man3/pthread_join.3.html