【Linux C | 多线程编程】线程的退出(return、pthread_exit、pthread_cancel函数详解)

😁博客主页😁:🚀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;
}

注意: returnpthread_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函数退出了。 这会发生什么事情?
首先要说明的是这不是常规的做法, 但是如果真的这样做了, 那么主线程将进入僵尸状态, 而其
他线程则不受影响, 会继续执行。

在这里插入图片描述
如果文章有帮助的话,点赞👍、收藏⭐,支持一波,谢谢 😁😁😁

  • 12
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wkd_007

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值