为什么加入一个线程最终会调用多个线程?

Why joining one thread ends up calling multiple threads?

我正在 Linux 上学习线程和使用 C 语言进行线程编程。我的理解是,加入一个线程只是简单地调用线程并等待它执行,就像等待子进程运行一样。但是我不确定为什么当我试图加入一个线程时,它最终调用了两个线程!

#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

void *start1()
{
    printf("Hello from Thread 1\n");

}

void *start2()
{
    printf("Hello from Thread 2\n");
}

void main()
{
    pthread_t t1,t2;

    pthread_create(&t1,NULL,start1,NULL);
    pthread_create(&t2,NULL,start2,NULL);
    pthread_join(t1,NULL); 
}

当我 运行 代码时,这里是输出:

[root@localhost]# ./a.out 
Hello from Thread 1
Hello from Thread 2

我原以为它只会调用 start1 的代码。

pthread_join 等待一个线程退出并且 pthread_create 创建 并启动 一个线程,无论您是否加入它。

在你的例子中,一个程序中有3个线程(包括主线程)。但是,如果执行 main 函数的主线程在 2 个附加线程之前退出,则整个程序将终止,附加线程可能没有机会输出任何内容。

最重要的是,你应该记住程序线程的执行顺序是不确定的,这包括但不一定保证同时执行。因此,在您的示例中,当您只等待来自主线程的一个附加线程时,无法确定第二个附加线程是否有机会在您等待时 运行 (并退出)第一个。

如果出于某种原因,您只希望一个线程 运行 那么您应该只启动一个线程(显然 :))或使用某种同步机制(例如 mutex or condition variable)将使第二个线程在执行它的工作之前等待某些条件发生。

pthread_join 函数只是让调用 pthread_join 的线程等待,直到它加入的线程完成执行。当进入 main 的线程正在等待线程 1 完成执行时,线程 1 和 2 可以 运行.

但是,该代码存在竞争条件。它永远不会等待线程 2 完成。所以输出可能是不可预测的。例如,调用 main 的线程可能 return 来自 main 并在线程 2 有机会开始之前终止进程。

以下建议代码:

  1. 干净地编译
  2. 执行所需的功能
  3. 在程序退出之前适当地等待线程退出
  4. thread 函数使用了正确的签名
  5. 正确退出 thread 函数
  6. 正确处理每个线程函数的函数参数
  7. 不包括头文件那些内容没有被使用

现在,建议的代码:

#include <pthread.h>
#include <stdio.h>
//#include <unistd.h>
//#include <stdlib.h>

void *start1( void * arg)
{
    (void)arg;
    printf( "Hello from Thread 1\n" );
    pthread_exit( NULL);
}

void *start2( void* arg)
{
    (void)arg;
    printf( "Hello from Thread 2\n" );
    pthread_exit( NULL );
}

int main( void )
{
    pthread_t t1,t2;

    pthread_create( &t1, NULL, start1, NULL );
    pthread_create( &t2, NULL, start2, NULL );
    pthread_join( t1, NULL ); 
    pthread_join( t2, NULL );
}