linux线程取消, pthread线程取消,pthread_testcancel用法

pthread_cancel

Linux中,线程在运行时如果想要取消,一种方法是调用pthread_cancel()函数,它的原型是:

/* Cancel THREAD immediately or at the next possibility.  */
extern int pthread_cancel (pthread_t __th);

参数pthread_t __th表示线程的id。

它的使用方法如下,

示例1

#include <stdio.h>
#include <pthread.h>
#include <sys/time.h>
#include <unistd.h>void* thread_func(void* arg)
{int count = 0;while(1) {printf("Thread is running, count: %d\n", count);count++;sleep(5);}printf("this is a thread cancel test 111\n");sleep(1);printf("test 222\n");printf("Thread cancellation requested. Exiting...\n");pthread_exit(NULL);return NULL;
}int main()
{pthread_t thread;pthread_create(&thread, NULL, thread_func, NULL);sleep(3);pthread_cancel(thread);pthread_join(thread, NULL);printf("Thread canceled successfully.\n");sleep(6);printf("end\n");return 0;
}

gcc -o threadcancel threadcancel.cpp -lpthread

输出为:

Thread is running, count: 0
Thread canceled successfully.
end

程序启动后会启动线程,线程执行while循环,在第一个循环中等待5秒。同时,main函数继续执行,在睡眠3秒后调用pthread_cancel。此时线程还在5秒睡眠中,它直接停止。

注意,while(1)循环后面的printf("this is a thread cancel test 111\n");及以后的内容都没有执行。

示例2

线程停止是在调用pthread_cancel立即停止吗,从上面看是的,我们在用其他示例验证一下:

#include <stdio.h>
#include <pthread.h>
#include <sys/time.h>
#include <unistd.h>void* thread_func(void* arg)
{int count = 0;while(count < 2) {printf("Thread is running, count: %d\n", count);count++;sleep(1);}printf("this is a thread cancel test 111\n");sleep(5);printf("test 222\n");printf("Thread cancellation requested. Exiting...\n");pthread_exit(NULL);return NULL;
}int main()
{pthread_t thread;pthread_create(&thread, NULL, thread_func, NULL);sleep(3);pthread_cancel(thread);pthread_join(thread, NULL);printf("Thread canceled successfully.\n");sleep(6);printf("end\n");return 0;
}

注意,这里的线程thread中的循环时间变了,从代码上看,调用pthread_cancel时,线程thread正处于睡眠5秒的时候,那么printf("this is a thread cancel test 111\n");应该会执行。

程序输出:

Thread is running, count: 0
Thread is running, count: 1
this is a thread cancel test 111
Thread canceled successfully.
end

这证明线程在调用pthread_cancel后立即停止。

疑问:什么样的线程都能被取消吗?

我开始以为是的,后来发现不是,比如下面的写法:

示例3

#include <stdio.h>
#include <pthread.h>
#include <sys/time.h>
#include <unistd.h>void* thread_func(void* arg)
{int count = 0;while(1) {count++;}printf("this is a thread cancel test 111\n");pthread_testcancel();printf("test 222\n");printf("Thread cancellation requested. Exiting...\n");pthread_exit(NULL);return NULL;
}int main()
{pthread_t thread;pthread_create(&thread, NULL, thread_func, NULL);usleep(1);pthread_cancel(thread);printf("call pthread_cancel.\n");pthread_join(thread, NULL);printf("Thread canceled successfully.\n");printf("end\n");return 0;
}

函数是一个死循环,运行的结果为:

call pthread_cancel.

然后就卡在那里。

调用pthread_cancel并没有成功。

后来我在这篇文章中关于pthread_cancel()的运用,取消点的理解-CSDN博客,明白了函数取消点的含义:

取消点:

我们都知道,程序的进行是一个时间过程而不是一个时间点。取消点的简单意思来说:
在一个时间段内,程序被挂起时,可以被取消的一个时间点。(APUE363页有详细的取消点函数)

也就是说,当线程出现 block(阻塞) 时,这个被阻塞的地方就是可被取消的地方。

更通俗的来说:就是线程A执行过程中,如果遇到其他线程B执行cancel函数,

线程继续运行,直到线程某一行代码出现阻塞
(如:pthread_testcancel、pthread_join、pthread_cond_wait、printf、sleep、read、write、等都是可以产生阻塞的函数)
此时就会退出。如果线程B还使用了pthread_join去获取返回值,返回值为整型且为PTHREAD_CANCELED(-1)
————————————————
版权声明:本文为CSDN博主「ySh_ppp」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/ySh_lC/article/details/120310393

如果函数中没有取消点,那就不会取消,就像上面程序那样。这些具有取消点功能的函数可以理解为系统调用,如果没有这些函数,就要手动加一个pthread_testcancel作为取消点。

pthread_testcancel

设置线程函数取消点,它的原型如下:

/* Test for pending cancellation for the current thread and terminatethe thread as per pthread_exit(PTHREAD_CANCELED) if it has beencancelled.  */
extern void pthread_testcancel (void);

示例4

#include <stdio.h>
#include <pthread.h>
#include <sys/time.h>
#include <unistd.h>void* thread_func(void* arg)
{int count = 0;while(1) {count++;pthread_testcancel();}printf("this is a thread cancel test 111\n");pthread_testcancel();printf("test 222\n");printf("Thread cancellation requested. Exiting...\n");pthread_exit(NULL);return NULL;
}int main()
{pthread_t thread;pthread_create(&thread, NULL, thread_func, NULL);usleep(1);pthread_cancel(thread);printf("call pthread_cancel.\n");pthread_join(thread, NULL);printf("Thread canceled successfully.\n");printf("end\n");return 0;
}

输出为:

call pthread_cancel.
Thread canceled successfully.
end

可以取消成功了。

不让线程被取消

如果不想让线程被取消,需要将线程设置为:

pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);

则pthread_testcancel和其他的系统调用就失灵了。

函数pthread_setcancelstate是可以改变线程遇到cancel信号的状态。
一共有两种状态:
1、对cancel信号有反应(默认):PTHREAD_CANCEL_ENABLE
2、不理会cancel信号        :PTHREAD_CANCEL_DISABLE

示例5

#include <stdio.h>
#include <pthread.h>
#include <sys/time.h>
#include <unistd.h>void* thread_func(void* arg)
{pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);int count = 0;while(1) {count++;pthread_testcancel();}printf("this is a thread cancel test 111\n");pthread_testcancel();printf("test 222\n");printf("Thread cancellation requested. Exiting...\n");pthread_exit(NULL);return NULL;
}int main()
{pthread_t thread;pthread_create(&thread, NULL, thread_func, NULL);usleep(1);pthread_cancel(thread);printf("call pthread_cancel.\n");pthread_join(thread, NULL);printf("Thread canceled successfully.\n");printf("end\n");return 0;
}

输出为:call pthread_cancel.

程序卡住,不会被取消。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/241955.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python连接数据库

文章目录 一、安装mysql二、SQLyog可视化操作三、python实现数据库单表类封装1. config 文件——config.py2. 封装类&#xff08;model&#xff09;——model.py3. 测试文件——test.py 一、安装mysql 官网安装&#xff0c;或者Windows64位直接在我的资源里面上传了mysql&…

【PostgreSQL】从零开始:(二十七)数据类型-UUID 类型

UUID 类型 UUID&#xff08;通用唯一标识符&#xff09;是一个128位的数字标识符&#xff0c;用于在计算机系统中唯一地标识实体。它的标准格式为32个十六进制数字&#xff0c;用连字符分隔成五个组&#xff0c;形式如&#xff1a;8-4-4-4-12。UUID在各种系统和平台上广泛使用…

华为OD机试 - 测试用例执行计划(Java JS Python C)

题目描述 某个产品当前迭代周期内有 N 个特性(F1,F2,......FN)需要进行覆盖测试,每个特性都被评估了对应的优先级,特性使用其 ID 作为下标进行标识。 设计了 M 个测试用例(T1,T2,......,TM),每个测试用例对应一个覆盖特性的集合,测试用例使用其 ID 作为下标进行标识,…

C/C++ 基础函数

memcpy&#xff1a;C/C语言中的一个用于内存复制的函数&#xff0c;声明在 string.h 中&#xff08;C是 cstring&#xff09; void *memcpy(void *destin, void *source, unsigned n);作用是&#xff1a;以source指向的地址为起点&#xff0c;将连续的n个字节数据&#xff0c;…

Acwing 周赛135 题解

A&#xff1a;https://www.acwing.com/problem/content/5378/ 思路&#xff1a;签到题&#xff0c;输出n/x即可。 代码&#xff1a; #include<bits/stdc.h> using namespace std; #define rep(i,a,b) for(int i(a);i<(b);i) #define lop(i,a,b) for(int i(a);i<…

Linux: config: CONFIG_NODES_SHIFT;numa;强制挂钩

文章目录 简介config NODES_SHIFT循环接口简介 node和numa算是强挂钩关系了。和node相关的,几乎全部是numa。所以不要疑惑node和numa的强关联性。 config NODES_SHIFT Redhat提供的是10,也就是支持1024个node,但实际上用不了这么多,但是为了通用性,设置了这么大,其实可…

HarmonyOS - 鸿蒙开发入门

文章目录 HarmonyOS核心资源特性&#xff1a;全场景终端HarmonyOS 版本 HarmonyOS 和 OpenHarmony教程资源开发环境开发工具 - DevEco开发语言 - ArkTS核心框架 - ArkUI 考证 HarmonyOS 开发交流秋秋群&#xff1a;23458659&#xff0c;V : ez-code&#xff0c;期待交流和合作 …

前端基础location的使用

概念 获取当前页面的地址信息&#xff0c;还可以修改某些属性&#xff0c;实现页面跳转和刷新等。 样例展示 window.location 含义.originURL 基础地址&#xff0c;包括协议名、域名和端口号.protocol协议 (http: 或 https:).host域名端口号.hostname域名.port端口号.pathname路…

自学SLAM(9)《第五讲:特征点法视觉里程计》作业

文章目录 1.ORB特征点1.1 ORB提取1.2 ORB描述1.3 暴力匹配1.4 最后&#xff0c;请结合实验&#xff0c;回答下⾯⼏个问题 2.从 E 恢复 R&#xff0c;t3.用 G-N 实现 Bundle Adjustment4.* 用 ICP 实现轨迹对齐 1.ORB特征点 1.1 ORB提取 ORB(Oriented FAST and BRIEF) 特征是 S…

计算机视觉基础(10)——深度学习与图像分类

前言 传统视觉算法采用手工设计特征与浅层模型&#xff0c;而手工设计特征依赖于专业知识&#xff0c;且泛化能力差。深度学习的出现改变了这一状况&#xff0c;为视觉问题提供了端到端的解决方案。在之前的课程中&#xff0c;我们已经学习了图像分类的传统知识。在本节课中&am…

【小白专用】php中如何清除session(四种方法)

Session是一种在Web开发中常用的状态管理机制&#xff0c;用来存储和共享用户会话信息。Session数据存储在服务器端&#xff0c;但由于Web应用的特性&#xff0c;可能会出现一些异常&#xff0c;比如过期、被污染等问题。在PHP中&#xff0c;我们可以通过以下几种方式清除Sessi…

c语言:求1/2+2/3+3/4+……n-1/n的和|练习题

一、题目 求1/22/33/4……n-1/n的和 如图&#xff1a; 二、思路分析 1、1/2、2/3、3/4……可以用(i/i1) 2、设置一个函数&#xff0c;求数的相加之和 三、代码截图【带注释】 四、源代码【带注释】 #include <stdio.h> int main() { int num; printf("输入…

javassmmysql医院线上线下全诊疗系统的设计与实现02210-计算机毕业设计项目选题推荐(免费领源码)

目 录 摘要 1 绪论 1.1背景及意义 1.2研究现状 1.3ssm框架介绍 1.4论文结构与章节安排 2 医院线上线下全诊疗系统系统分析 2.1 可行性分析 2.1.1 技术可行性分析 2.1.2 经济可行性分析 2.1.3 法律可行性分析 2.2 系统功能分析 2.2.1 功能性分析 2.2.2 非功能性分…

Git常用命令及解释说明

目录 前言1 git config2 git init3 git status4 git add5 git commit6 git reflog7 git log8 git reset结语 前言 Git是一种分布式版本控制系统&#xff0c;广泛用于协作开发和管理项目代码。了解并熟练使用Git的常用命令对于有效地管理项目版本和历史记录至关重要。下面是一些…

at java.net.URLClassLoader.findClass(URLClassLoader.java:382) 问题排查

一、问题的提出 之前写的框架类都没有打成jar包&#xff0c;无论是在idea环境还是在真实运行环境&#xff0c;都运行正常。后来把项目改成了maven项目&#xff0c;一个项目里许多模块&#xff0c;框架打包以后在idea运行正常&#xff0c;但是在真实环境下&#xff0c;就提示没…

springcloud-gateway-2-鉴权

目录 一、跨域安全设置 二、GlobalFilter实现全局的过滤与拦截。 三、GatewayFilter单个服务过滤器 1、原理-官方内置过滤器 2、自定义过滤器-TokenAuthGatewayFilterFactory 3、完善TokenAuthGatewayFilterFactory的功能 4、每一个服务编写一个或多个过滤器&#xff0c…

关于“Python”的核心知识点整理大全39

目录 ​编辑 14.1.5 将 Play 按钮切换到非活动状态 game_functions.py 14.1.6 隐藏光标 game_functions.py game_functions.py 14.2 提高等级 14.2.1 修改速度设置 settings.py settings.py settings.py game_functions.py 14.2.2 重置速度 game_functions.py 1…

DPDK系列之四十硬件加速和功能卸载

一、硬件卸载 硬件加速&#xff0c;听名字就是明白是利用硬件加速。不太准确&#xff0c;硬件加速其实更有效进行硬件的分工&#xff0c;通过分工实现硬件的整体的效率的提升。其实硬件卸载就是硬件加速&#xff0c;而实现硬件加速就需要进行功能卸载&#xff0c;整体上就可以…

饥荒Mod 开发(二一):超大便携背包,超大物品栏,永久保鲜

饥荒Mod 开发(二十)&#xff1a;显示打怪伤害值 源码 游戏中的物品栏容量实在太小了&#xff0c;虽然可以放在箱子里面但是真的很不方便&#xff0c;外出一趟不容易看到东西都不能捡。实在是虐心。 游戏中的食物还有变质机制&#xff0c;时间长了就不能吃了&#xff0c;玩这个游…

【高数定积分求解旋转体体积】 —— (上)高等数学|定积分|柱壳法|学习技巧

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 &#x1f4ab;个人格言:"没有罗马,那就自己创造罗马~" 目录 Shell method Setting up the Integral 例题 Example 1: Example 2: Example 3: Computing…