线程退出
线程中提供了一个用于单个线程退出的函数——pthread_exit(),该函数位于函数库pthread.h中,其声明如下:
void pthread_exit(void *retval);
在之前的案例中使用的return和exit()虽然也有退出功能,但return用于退出函数,使函数返回函数调用处;exit()用于退出进程,若在线程中调用该函数,那么该线程所处的进程也会退出,如此势必会影响进程中线程的执行。为避免这个问题,保证程序中的线程能逐个退出,Linux系统中又提供了pthread_exit()函数。
pthread_exit()函数没有返回值,其参数retval表示线程的退出状态,通常设置为NULL。下面通过一个案例来展示pthread_exit()函数的用法。
案例3:在一个进程中创建4个子线程,分别使用pthread_exit()函数、return、exit()使其中一个线程退出,观察其它线程的执行状况。
1 #include <pthread.h>
2 #include <stdio.h>
3 #include <unistd.h>
4 #include <stdlib.h>
5 void *tfn(void *arg)
6 {
7 long int i;
8 i = (long int)arg; //强转
9 if (i == 2)
10 pthread_exit(NULL);
11 sleep(i); //通过i来区别每个线程
12 printf("I'm %dth thread, Thread_ID = %lu\n", i+1, pthread_self());
13 return NULL;
14 }
15 int main(int argc, char *argv[])
16 {
17 long int n = 5, i;
18 pthread_t tid;
19 if (argc == 2)
20 n = atoi(argv[1]);
21 for (i = 0; i < n; i++) {
22 //将i转换为指针,在tfn中再强转回整形
23 pthread_create(&tid, NULL, tfn, (void *)i);
24 }
25 sleep(n);
26 printf("I am main, I'm a thread!\n"
27 "main_thread_ID = %lu\n", pthread_self());
28 return 0;
29 }
编译案例3,执行程序,执行结果如下:
I'm 1th thread, Thread_ID = 140427927828224
I'm 2th thread, Thread_ID = 140427917338368
I'm 4th thread, Thread_ID = 140427896358656
I'm 5th thread, Thread_ID = 140427885868800
I am main, I'm a thread!
main_thread_ID = 140427927836416
由执行结果可知,使用pthread_exit()函数时,只有调用该函数的线程会退出。若将案例3中第10行代码改为“return;”,编译程序,终端打印的信息与案例3执行结果相同;若将案例3中第10行代码改为“exit(0);”,编译程序,终端打印信息如下:
I'm 1th thread, Thread_ID = 139918783432448
多次执行,发现有时甚至连如上的一行信息都没有打印,这是因为,多个线程在系统中是并行执行的,在第1、2个线程尚未结束时,第3个线程就已经在cpu上运行,且由于其中调用了exit()函数,第3个线程在运行到第10行代码时,会使整个进程退出,因此该进程中的所有线程都无法再被执行。