【多线程编程学习笔记6】终止线程执行,千万别踩这个坑!_终止线程执行,千万别踩这个坑!

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Golang全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip1024b (备注go)
img

正文

#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h> //调用 sleep() 函数
void * thread_Fun(void * arg) {
printf(“新建线程开始执行\n”);
//插入无限循环的代码,测试 pthread_cancel()函数的有效性
while(1);
}
int main()
{
pthread_t myThread;
void * mess;
int value;
int res;
res = pthread_create(&myThread, NULL, thread_Fun, NULL);
if (res != 0) {
printf(“线程创建失败\n”);
return 0;
}
sleep(1);
//令 myThread 线程终止执行
res = pthread_cancel(myThread);
if (res != 0) {
printf(“终止 myThread 线程失败\n”);
return 0;
}
printf(“等待 myThread 线程执行结束:\n”);
res = pthread_join(myThread, &mess);
if (res != 0) {
printf(“等待线程失败\n”);
return 0;
}
if (mess == PTHREAD_CANCELED) {
printf(“myThread 线程被强制终止\n”);
}
else {
printf(“error\n”);
}
return 0;
}

https://raw.githubusercontent.com/xkyvvv/blogpic/main/pic1/image-20210711094517042.png

程序中,主线程( main() 函数)试图调用 pthread_cancel() 函数终止 myThread 线程执行。从运行结果不难发现,pthread_cancel() 函数成功发送了 Cancel 信号,但目标线程仍在执行。

也就是说,接收到 Cancel 信号的目标线程并没有立即处理该信号,或者说目标线程根本没有理会此信号。解决类似的问题,我们就需要搞清楚目标线程对 Cancel 信号的处理机制。

根据上节的内容,pthread_join会阻塞调用它的线程,因此程序在执行完printf(“等待 myThread 线程执行结束:\n”);后就会一直阻塞在res = pthread_join(myThread, &mess);等待目标线程myThread执行完毕

线程对Cancel信号的处理

对于默认属性的线程,当有线程借助 pthread_cancel() 函数向它发送 Cancel 信号时,它并不会立即结束执行,而是选择在一个适当的时机结束执行。

所谓适当的时机,POSIX 标准中规定,当线程执行一些特殊的函数时,会响应 Cancel 信号并终止执行,比如常见的 pthread_join()、pthread_testcancel()、sleep()、system() 等,POSIX 标准称此类函数为“cancellation points”(中文可译为“取消点”)。

POSIX 标准中明确列举了所有可以作为取消点的函数,这里不再一一罗列,感兴趣的读者可以自行查阅 POSIX 标准手册。

此外,<pthread.h> 头文件还提供有 pthread_setcancelstate() 和 pthread_setcanceltype() 这两个函数,我们可以手动修改目标线程处理 Cancel 信号的方式。

1、pthread_setcancelstate()函数

借助 pthread_setcancelstate() 函数,我们可以令目标线程处理 Cancal 信号,也可以令目标线程不理会其它线程发来的 Cancel 信号。

pthread_setcancelstate() 函数的语法格式如下:

int pthread_setcancelstate( int state , int * oldstate );

  1. state 参数有两个可选值,分别是:
  • PTHREAD_CANCEL_ENABLE(默认值):当前线程会处理其它线程发送的 Cancel 信号;
  • PTHREAD_CANCEL_DISABLE:当前线程不理会其它线程发送的 Cancel 信号,直到线程状态重新调整为 PTHREAD_CANCEL_ENABLE 后,才处理接收到的 Cancel 信号。
  1. oldtate 参数用于接收线程先前所遵循的 state 值,通常用于对线程进行重置。如果不需要接收此参数的值,置为 NULL 即可。

pthread_setcancelstate() 函数执行成功时,返回数字 0,反之返回非零数。

2、pthread_setcanceltype()函数

当线程会对 Cancel 信号进行处理时,我们可以借助 pthread_setcanceltype() 函数设置线程响应 Cancel 信号的时机。

pthread_setcanceltype() 函数的语法格式如下:

int pthread_setcanceltype( int type , int * oldtype );

  1. type 参数有两个可选值,分别是:
  • PTHREAD_CANCEL_DEFERRED(默认值):当线程执行到某个可作为取消点的函数时终止执行;
  • PTHREAD_CANCEL_ASYNCHRONOUS:线程接收到 Cancel 信号后立即结束执行。
  1. oldtype 参数用于接收线程先前所遵循的 type 值,如果不需要接收该值,置为 NULL 即可。

pthread_setcanceltype() 函数执行成功时,返回数字 0,反之返回非零数。

接下来通过一个实例给大家演示以上两个函数的功能和用法:

#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h> //调用 sleep() 函数

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Go)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
可以添加V获取:vip1024b (备注Go)**
[外链图片转存中…(img-DXWveio7-1713441028619)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值