为什么加入一个线程最终会调用多个线程?
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 有机会开始之前终止进程。
以下建议代码:
- 干净地编译
- 执行所需的功能
- 在程序退出之前适当地等待线程退出
- 为
thread
函数使用了正确的签名
- 正确退出
thread
函数
- 正确处理每个线程函数的函数参数
- 不包括头文件那些内容没有被使用
现在,建议的代码:
#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 );
}
我正在 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 有机会开始之前终止进程。
以下建议代码:
- 干净地编译
- 执行所需的功能
- 在程序退出之前适当地等待线程退出
- 为
thread
函数使用了正确的签名 - 正确退出
thread
函数 - 正确处理每个线程函数的函数参数
- 不包括头文件那些内容没有被使用
现在,建议的代码:
#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 );
}