😁博客主页😁:🚀https://blog.csdn.net/wkd_007🚀
🤑博客内容🤑:🍭嵌入式开发、Linux、C语言、C++、数据结构、音视频🍭
🤣本文内容🤣:🍭介绍线程的退出 🍭
😎金句分享😎:🍭你不能选择最好的,但最好的会来选择你——泰戈尔🍭
⏰发布时间⏰:2024-03-27 00:42:51
本文未经允许,不得转发!!!
🎄一、概述
本文主要介绍线程退出的几种方式,以及各种方式之间的区别。
然后会介绍线程退出会使用的函数pthread_exit、pthread_cancel。
最后,介绍线程的返回值可以通过什么方式告知已连接的线程。
🎄二、线程会终止,进程不会终止 的三种方式
下面的三种方法中,线程会终止,但是进程不会终止(如果线程不是进程组里的最后一个线程的话):
- 创建线程时的
start_routine
函数执行了return
, 并且返回指定值。 - 线程调用
pthread_exit
。 - 其他线程调用了
pthread_cancel
函数取消了该线程。
例子一:线程函数使用 return 终止线程
// 06_pthread_return.c
// gcc 06_pthread_return.c -l pthread
#include <stdio.h>
#include <pthread.h>
void *func(void *arg)
{
int *parg = arg;
printf("this thread arg is %d, my threadID is %lx \n", *parg, (unsigned long)pthread_self());
return NULL;
}
int main()
{
int arg=10;
pthread_t threadId;
pthread_create(&threadId, NULL, func, &arg);
return 0;
}
例子二:线程函数使用 pthread_exit 终止线程
// 06_pthread_exit.c
// gcc 06_pthread_exit.c -l pthread
#include <stdio.h>
#include <pthread.h>
void *func(void *arg)
{
int *parg = arg;
printf("this thread arg is %d, my threadID is %lx \n", *parg, (unsigned long)pthread_self());
pthread_exit(NULL);
}
int main()
{
int arg=10;
pthread_t threadId;
pthread_create(&threadId, NULL, func, &arg);
return 0;
}
例子三:其他线程调用 pthread_cancel 终止指定线程
// 06_pthread_cancel.c
// gcc 06_pthread_cancel.c -l pthread
#include <stdio.h>
#include <pthread.h>
void *func(void *arg)
{
int *parg = arg;
printf("this thread arg is %d, my threadID is %lx \n", *parg, (unsigned long)pthread_self());
while(1);
}
int main()
{
int arg=10;
pthread_t threadId;
pthread_create(&threadId, NULL, func, &arg);
pthread_cancel(threadId);
pthread_join(threadId, NULL);
return 0;
}
注意: return
和pthread_exit
是有区别的,return只有在线程执行函数调用才会终止线程,而 pthread_exit 在线程任意层级函数调用都会式该线程终止。
🎄三、pthread_exit、pthread_cancel 函数
在线程退出时,可能用使用到 pthread_exit、pthread_cancel 函数,这小节简单介绍一下这两个函数,使用例子见上一小节。
pthread_exit 函数原型:
#include <pthread.h>
void pthread_exit(void *retval);
Compile and link with -pthread.
函数pthread_exit()
终止调用线程,并通过retval
返回一个值,如果线程是可连接(使用pthread_join连接)的,该值可用于调用 pthread_join
的同一进程中的另一个线程。
pthread_cancel 函数原型:
#include <pthread.h>
int pthread_cancel(pthread_t thread);
Compile and link with -pthread.
pthread_cancel()
函数向thread
参数指定的线程发送一个取消请求。目标线程是否以及何时对取消请求作出反应取决于该线程控制的两个属性:其可取消状态和类型。
🎄四、线程返回值
关于线程的返回值,首先要清楚一点,不能将线程函数的种局部变量的地址作为返回值。因为线程退出后,线程函数栈上的局部变量可能就不复存在了。
线程返回值是void*
类型的,有两种方式可以返回线程的返回值,一是在线程执行函数中,调用return ret
;另一个是通过pthread_exit(ret)
返回。
正确返回线程返回值的4个方法:
- 如果是数值,则可以使用
pthread_exit((int*) val);
,将数值或变量转成指针传出。- 使用全局变量返回。其他线程调用pthread_join时也可见这个变量。
- 将返回值填入到用malloc在堆上分配的空间里。因为堆上的空间不会随着线程的退出而释放, 所以pthread_join可以取出返回值
- 使用字符串常量, 如
pthread_exit(“hello, world”)
。因为字符串常量有静态存储的生存期限。
🎄五、总结
本文介绍了线程会终止,进程不会终止
的三种方式。然后介绍线程退出的两个函数,最后介绍线程退出返回值。
思考:如果进程的其他线程在执行的情况下,主线程调用pthread_exit函数退出了。 这会发生什么事情?
首先要说明的是这不是常规的做法, 但是如果真的这样做了, 那么主线程将进入僵尸状态, 而其
他线程则不受影响, 会继续执行。
如果文章有帮助的话,点赞👍、收藏⭐,支持一波,谢谢 😁😁😁