1. 多线程退出的方式如下:
- 线程调用pthread.exit()
- 线程调用return
- 线程所属进程结束
- 线程被其它线程通知结束或者结束
前两种方式也称为线程的主动结束,是理想状况,但是需要注意一点,线程结束(非分离状态),资源却没有释放,需要调用pthread_join()
后两种称为被动结束,其中第三种是很异常的情况,而第四种有时是我们希望这么做的, 比如某个线程非常耗时,我们希望线程结束
2. 主动结束
return 只是结束其所属的函数,而pthread_exit则是结束其所属的线程,若在线程函数中,则二者没有区别
#include <stdio.h> #include <pthread.h> #include <unistd.h> static int gs_num; void *pth_fun(void *arg) { printf("I am a pthread\n"); gs_num = 100; pthread_exit((void*)&gs_num); } int main(void) { pthread_t pth; int ret = pthread_create(&pth, NULL, pth_fun, NULL); if (ret) { printf("create pthread error\n"); return 0; } int *data = 0; pthread_join(pth, (void*)&data); printf("data = %d\n", *data); sleep(2); printf("hello world!\n"); return 0; }
执行结果如下:
kunmzhao@build-245:~$ gcc 1.c -pthread
kunmzhao@build-245:~$ ./a.out
I am a pthread
data = 100
hello world!
改成pthread_join改成return,效果一样
3. 被动结束
其它线程发送信号取消线程
3.1 pthread_kill
int pthread_kill(pthread_t threadId, int signal)
1) threadId:线程号
2) signal:信号
返回值:成功:0,失败:errno
注意:1. 该函数不仅仅用来结束线程,通过signal可传递多个信号
2. 接收该信号的线程需要事先注册该信号的处理函数,类似Qt的信号槽
3. on_signal_fun中的pthread_exit换成return, 则不能结束线程
4. 该函数可以判断某个线程是都存活,发送信号为0,若pthread_kill 的返回值为 ESRCH ,则线程已经退出或者不存在
#include <stdio.h> #include <pthread.h> #include <unistd.h> #include <signal.h> void on_signal_fun(int sig) { printf("sig = %d\n", sig); printf("received a quit signal\n"); pthread_exit(NULL); // exit pthread } void *pth_fun(void *arg) { signal(SIGQUIT, on_signal_fun); // register the exit function printf("I am a pthread\n"); while (1) { continue; } return NULL; } int main(void) { pthread_t pth; int ret = pthread_create(&pth, NULL, pth_fun, NULL); if (ret) { printf("create pthread error\n"); return 0; } sleep(5); pthread_kill(pth, SIGQUIT); pthread_join(pth, NULL); printf("hello world!\n"); return 0; }
运行结果如下:
kunmzhao@build-245:~$ gcc 1.c -pthread
kunmzhao@build-245:~$ ./a.out
I am a pthread
sig = 3
received a quit signal
hello world!
kunmzhao@build-245:~$
3.2 pthread_cancel
int pthread_cancel(pthread_t thread)
thread:线程号
返回值:成功:0, 失败:errno
注意点:1. 该函数发送成功,线程也不会立即结束,只有在线程调用库函数时候才会结束
2. 针对第一点可以用 void pthread_testcancel(void) 进行判断,尤其在死循环中尤为好用
#include <stdio.h> #include <pthread.h> #include <unistd.h> #include <signal.h> void *pth_fun(void *arg) { printf("I am a pthread\n"); int i = 0; while (1) { i++; pthread_testcancel(); } return NULL; } int main(void) { pthread_t pth; int ret = pthread_create(&pth, NULL, pth_fun, NULL); if (ret) { printf("create pthread error\n"); return 0; } sleep(5); pthread_cancel(pth); pthread_join(pth, NULL); printf("hello world!\n"); return 0; }
运行结果如下:
kunmzhao@build-245:~$ gcc 1.c -lpthread
kunmzhao@build-245:~$ ./a.out
I am a pthread
hello world!
如果将上述代码中的pthrea_testcancel()去掉, 虽然pthread_cancel信号发送成功, 但是线程却不会退出
浙公网安备 33010602011771号