在 C 语言中使用 pthread_join 函数
本文将介绍几种如何在 C 语言中使用 pthread_join
函数的方法。
使用 pthread_join
函数等待线程终止
程序使用 pthread_create
函数创建线程,通常,它等待它们通过 pthread_join
函数终止。pthread_join
仅接受两个参数:用于指定等待线程的线程 ID 和指向可以存储指定线程的退出状态的 void*
的指针。如果用户不想检索等待的线程的退出代码,则应将 NULL
值作为第二个参数传递。在下面的示例中,我们演示了创建 8 个线程并在每个线程中执行 printHello
函数的程序。然后,调用线程在循环中等待带有 pthread_join
调用的每个线程。注意,我们还将线程的退出状态代码存储在 retval
变量中,并通过将其强制转换为 int
来打印其值。请注意,如果线程被取消,则将 PTHREAD_CANCELED
值放置在 retval
地址中。
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <errno.h>
#ifndef NUM_THREADS
#define NUM_THREADS 8
#endif
void *printHello(void *threadid) {
long tid;
tid = (long)threadid;
printf("Hello from thread %ld, pthread ID - %lu\n", tid, pthread_self());
return NULL;
}
int main(int argc, char const *argv[]) {
pthread_t threads[NUM_THREADS];
int rc;
long t;
for (t = 0; t < NUM_THREADS; t++) {
rc = pthread_create(&threads[t], NULL, printHello, (void *)t);
if (rc) {
printf("ERORR; return code from pthread_create() is %d\n", rc);
exit(EXIT_FAILURE);
}
}
int ret;
for (t = 0; t < NUM_THREADS; t++) {
void *retval;
ret = pthread_join(threads[t], &retval);
if (retval == PTHREAD_CANCELED)
printf("The thread was canceled - ");
else
printf("Returned value %d - ", (int)retval);
}
pthread_exit(NULL);
}
输出:
Hello from thread 0, pthread ID - 140716669929216
Hello from thread 1, pthread ID - 140716661536512
Hello from thread 2, pthread ID - 140716653143808
Hello from thread 3, pthread ID - 140716644751104
Hello from thread 5, pthread ID - 140716627965696
Hello from thread 4, pthread ID - 140716636358400
Hello from thread 6, pthread ID - 140716550387456
Hello from thread 7, pthread ID - 140716541994752
使用 pthread_join
函数返回值检查错误
与设置 errno
全局变量的函数相比,pthread_join
函数返回的整数值还指示不同的错误代码。如果调用成功,则返回值为 0
,这可以确保给定线程已终止。如果返回的整数等于 EDEADLK
,则报告检测到死锁。如果返回 EINVAL
值,则给定线程不可连接,如果该值等于 ESRCH
,则表明找不到给定线程 ID。在这种情况下,我们实现 switch
语句以检查每种情况,并将相应的消息打印到 stdout
。
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <errno.h>
#ifndef NUM_THREADS
#define NUM_THREADS 8
#endif
void *printHello(void *threadid) {
long tid;
tid = (long)threadid;
printf("Hello from thread %ld, pthread ID - %lu\n", tid, pthread_self());
return NULL;
}
int main(int argc, char const *argv[]) {
pthread_t threads[NUM_THREADS];
int rc;
long t;
for (t = 0; t < NUM_THREADS; t++) {
rc = pthread_create(&threads[t], NULL, printHello, (void *)t);
if (rc) {
printf("ERORR; return code from pthread_create() is %d\n", rc);
exit(EXIT_FAILURE);
}
}
int ret;
for (t = 0; t < NUM_THREADS; t++) {
void *retval;
ret = pthread_join(threads[t], &retval);
if (retval == PTHREAD_CANCELED)
printf("The thread was canceled - ");
else
printf("Returned value %d - ", (int)retval);
switch (ret) {
case 0:
printf("The thread joined successfully\n");
break;
case EDEADLK:
printf("Deadlock detected\n");
break;
case EINVAL:
printf("The thread is not joinable\n");
break;
case ESRCH:
printf("No thread with given ID is found\n");
break;
default:
printf("Error occurred when joining the thread\n");
}
}
pthread_exit(NULL);
}
输出:
Hello from thread 0, pthread ID - 140082577512192
Hello from thread 1, pthread ID - 140082569119488
Hello from thread 3, pthread ID - 140082552334080
Hello from thread 5, pthread ID - 140082535548672
Hello from thread 6, pthread ID - 140082527155968
Returned value 0 - The thread joined successfully
Hello from thread 4, pthread ID - 140082543941376
Hello from thread 2, pthread ID - 140082560726784
Returned value 0 - The thread joined successfully
Returned value 0 - The thread joined successfully
Returned value 0 - The thread joined successfully
Hello from thread 7, pthread ID - 140082518763264
Returned value 0 - The thread joined successfully
Returned value 0 - The thread joined successfully
Returned value 0 - The thread joined successfully
Returned value 0 - The thread joined successfully
Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.
LinkedIn