何时使用pthread_exit()以及何时在Linux中使用pthread_join()?

我对pthreads是新的,我正在试图理解它。 我看到一些像下面这样的例子。

我可以看到main()被API pthread_exit()阻塞,我看到了主函数被API pthread_join()阻塞的例子。 我无法理解何时使用什么?

我指的是以下网站 – https://computing.llnl.gov/tutorials/pthreads/ 。 我无法得到何时使用pthread_join()和何时使用pthread_exit()

有人可以解释吗? 此外,一个很好的教程链接pthreads将不胜感激。

 #include <pthread.h> #include <stdio.h> #define NUM_THREADS 5 void *PrintHello(void *threadid) { long tid; tid = (long)threadid; printf("Hello World! It's me, thread #%ld!\n", tid); pthread_exit(NULL); } int main (int argc, char *argv[]) { pthread_t threads[NUM_THREADS]; int rc; long t; for(t=0; t<NUM_THREADS; t++){ printf("In main: creating thread %ld\n", t); rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t); if (rc){ printf("ERROR; return code from pthread_create() is %d\n", rc); exit(-1); } } /* Last thing that main() should do */ pthread_exit(NULL); 

正如openpub文档中所解释的那样,

pthread_exit()将退出调用它的线程。

在你的情况下,由于主要调用它,主线程将终止,而产生的线程将继续执行。 这主要用于主线程只需要产生线程并让线程完成工作的情况

除非目标线程终止,否则pthread_join将挂起已经调用它的线程的执行

这对于在主线程中进一步处理之前等待线程终止的情况非常有用。

一个很好的基础知识链接

pthread_exit终止调用线程,而pthread_join暂停执行调用线程,直到目标线程完成执行。

在开放组文档中对它们进行了详细的解释:

  • 了pthread_exit
  • 在pthread_join

两种方法都可以确保您的过程在所有线程结束之前不会结束。

连接方法让main函数的线程显式等待所有要“加入”的线程。

pthread_exit方法以受控方式终止你的main函数和线程。 main有结束main的特殊性,否则将终止你的整个过程,包括所有其他线程。

为了这个工作,你必须确保你的线程没有使用在main函数中声明的局部变量。 该方法的优点是你的main不必知道在你的进程中已经启动的所有线程,例如,因为其他线程本身创建了一个main不知道的新线程。

您不需要在您的特定代码中调用pthread_exit(3)

通常, main线程不应该调用pthread_exit ,而应该经常调用pthread_join(3) 等待其他线程完成。

在你的PrintHello函数中,你不需要调用pthread_exit因为它从返回后是隐含的。

所以你的代码应该是:

 void *PrintHello(void *threadid) { long tid = (long)threadid; printf("Hello World! It's me, thread #%ld!\n", tid); return threadid; } int main (int argc, char *argv[]) { pthread_t threads[NUM_THREADS]; int rc; intptr_t t; // create all the threads for(t=0; t<NUM_THREADS; t++){ printf("In main: creating thread %ld\n", (long) t); rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t); if (rc) { fprintf(stderr, "failed to create thread #%ld - %s\n", (long)t, strerror(rc)); exit(EXIT_FAILURE); }; } pthread_yield(); // useful to give other threads more chance to run // join all the threads for(t=0; t<NUM_THREADS; t++){ printf("In main: joining thread #%ld\n", (long) t); rc = pthread_join(&threads[t], NULL); if (rc) { fprintf(stderr, "failed to join thread #%ld - %s\n", (long)t, strerror(rc)); exit(EXIT_FAILURE); } } } 

pthread_exit()API

如已经注意到的,用于调用线程终止。 在对这个函数的调用之后,开始一个复杂的清除机制。 当它完成时,线程被终止。 pthread_exit()API也在pthread_create()创建的线程中发生对return()例程的调用时隐式调用。 实际上,对pthread_exit()的调用和对pthread_exit()的调用具有相同的效果,被从pthread_create()创建的线程中调用。

区分main()函数启动时隐式创建的初始线程和pthread_create()创建的线程是非常重要的。 从main()函数调用return()例程隐式调用exit()系统调用,整个过程终止。 没有线程清理机制启动。 从main()函数调用pthread_exit()会导致清理机制启动,并在完成工作时初始线程终止。

当从main()函数调用pthread_exit()时,整个进程(以及其他线程)会发生什么情况取决于PTHREAD实现。 例如,在IBM OS / 400实现中,当从main()函数调用pthread_exit()时,整个进程终止,包括其他线程。 其他系统可能会有不同的表现。 在大多数现代Linux机器上,从初始线程调用pthread_exit()并不终止整个进程,直到所有线程终止。 如果要编写便携式应用程序,请小心使用main()中的pthread_exit()。

pthread_join()API

是一个等待线程终止的便捷方式。 您可以编写自己的函数,等待线程终止,可能更适合您的应用程序,而不是使用pthread_join()。 例如,它可以是基于等待条件变量的函数。

我会推荐阅读一本David R. Butenhof的书“用POSIX线程编程”。 它很好地解释了讨论的主题(和更复杂的东西)(尽管一些实现细节,如主函数中的pthread_exit用法,并不总是反映在书中)。

pthread_exit()将终止调用线程并退出调用线程(但调用线程使用的资源不会释放到操作系统,如果它不从主线程分离)。

pthrade_join()将等待或阻塞调用线程,直到目标线程未终止。 简而言之,它将等待退出目标线程。

在你的代码中,如果你在pthread_exit()之前把PrintHello函数放入睡眠(或者延迟),那么主线程可能会退出并终止整个进程,尽管你的PrintHello函数没有完成,它将会终止。 如果在main调用pthread_exit()之前使用pthrade_join()函数,它将阻塞主线程并等待完成调用线程( PrintHello )。

嗯。

来自http://pubs.opengroup.org/onlinepubs/009604599/functions/pthread_exit.html&#x7684; POSIX pthread_exit说明:

 After a thread has terminated, the result of access to local (auto) variables of the thread is undefined. Thus, references to local variables of the exiting thread should not be used for the pthread_exit() value_ptr parameter value. 

这似乎与本地main()线程变量将保持可访问的想法相悖。