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