Linux-C编程 / 多线程 / 如何终止某个线程?

示例 demo

最简单的 demo:

static void* thread1_func(void *arg)
{int i = 0;// able to be cancelpthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);for(i=0; ; i++) {printf("thread1 %d\n", i);sleep(1);}
}int main(int argc, char **argv)
{pthread_t t;void *res;pthread_create(&t, NULL, thread1_func, NULL);sleep(3);pthread_cancel(t);          // cancel thread1pthread_join(t, &res);      // wait thread1if (res == PTHREAD_CANCELED)printf("thread1 was terminate by cancel\n");elseprintf("thread1 was not terminate by cancel\n");exit(EXIT_SUCCESS);
}

为了突出重点,省略了检查返回值。

运行效果:

thread1 0
thread1 1
thread1 2
thread1 was terminate by cancel

主线程先创建线程 thread1,然后睡眠 3 秒后发出终止 thread1 的请求。

接收到终止请求后,thread1 会在合适的时机被终止掉。

主线程通过 pthread_join() 阻塞等待 thread1 退出。

几个要点

线程终止的 4 种方式:

  1. 线程的执行函数返回了,这和 main() 函数结束类似。

  2. 线程调用了 pthread_exit() 函数,这和调用 exit() 返回类似。

  3. 线程被另一个线程通过 pthread_cancel() 函数取消,这和通过kill() 发送 SIGKILL 信号类似。

  4. 进程终止了,则进程中的所有线程也会终止。

取消某个线程的常规步骤

被取消的线程:

  1. 允许取消,pthread_setcancelstate(),参数可选值:

  • PTHREAD_CANCEL_ENABLE,这是默认值;

  • PTHREAD_CANCEL_DISABLE;

  • 设置取消类型,pthread_setcanceltype(),参数可选值:

    • PTHREAD_CANCEL_ASYNCHRONOUS,异步方式,当发出取消请求后,线程可能会在任何点被杀死。

    • PTHREAD_CANCEL_DEFERRED,延迟方式,线程只会在特定的取消点(cancellation points,调用某个函数前)被杀死。

    发起取消的线程:

    1. 发送取消要求,pthread_cancel(),发出取消请求后,pthread_cancel() 当即返回,不会等待目标线程的退出。

    2. 等待取消完成,pthread_join()。

    哪些函数是取消点?

    POSIX.1 指定了哪些函数一定是取消点:

    点击查看大图

    更多关于取消点的介绍:

    $ man 7 pthreadsCancellation points...accept()aio_suspend()clock_nanosleep()close()...
    

    阅读开源软件 MJPG-streamer

    MJPG-streamer 是什么?

    简单地说,就是一个开源的流媒体服务器:

    https://github.com/jacksonliam/mjpg-streamer

    通过 mjpg-streamer,你可以通过 PC 浏览器访问到板子上的摄像头图像。

    MJPG-streamer 是如何结束工作线程的?

    MJPG-streamer 运行时一般会有 3 个线程:

    • 主线程;

    • 负责数据的输入的线程 (例如 camera capture thread);

    • 负责输出数据的线程 (例如 http server thread).

    以 http server thread 为例:

    plugins/output_http/httpd.cvoid *server_thread(void *arg)
    {...pthread_cleanup_push(server_cleanup, pcontext);// 处理连接while(!pglobal->stop) {...}pthread_cleanup_pop(1);
    }
    

    pthread_cleanup_push() 用于注册清理函数到栈中,当线程遭取消时,会沿该栈自顶向下依次执行清理函数。

    当用户通过按下 ctrl + c 要求结束程序时,主线程会要求杀掉 http server thread 等各种线程:

    static void signal_handler(int sig)
    {for(i = 0; i < global.outcnt; i++) {...pthread_cancel(servers[id].threadID);...}
    }
    

    接下来,当 http server thread 遇到某个取消点时,server_cleanup() 会被调用以完成清理工作。

    这里只是简单地分析一下,MJPG-Streamer 里多线程相关的代码挺复杂的,有兴趣的小伙伴们自行阅读吧。

    相关参考

    • 开源软件 / MJPG-Streamer

    • Linux 系统编程(第2版) / 7.7.6 终止线程

    • Linux 程序设计(第4版) / 12.7 取消一个线程

    • Linux-Unix 系统编程手册 / 32 线程:线程取消

    • Unix 环境高级编程 / 11.5 线程终止

    思考技术,也思考人生

    要学习技术,更要学习如何生活

    你和我各有一个苹果,如果我们交换苹果的话,我们还是只有一个苹果。但当你和我各有一个想法,我们交换想法的话,我们就都有两个想法了。

    推荐阅读:

    专辑|Linux文章汇总

    专辑|程序人生

    专辑|C语言

    我的知识小密圈

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

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

相关文章

PaddlePaddle入门——基本概念

最近报了百度的深度学习认证&#xff0c;需要使用Paddle进行编程实现&#xff0c;找了一些基础教程&#xff0c;特意记录下来&#xff0c;加深印象。思维导图如下&#xff1a; 一、Paddle的内部执行流程 二、内部详解 1.Variable&#xff08;变量&#xff09; &#xff08;1…

我会在天堂爱你.

★☆你相信爱情吗&#xff1f;☆★如果你觉得这篇文章很好的话&#xff01;那么请把这篇信息传给20位网友或以上&#xff0c;那天下的有情人也会终成眷属&#xff0c;当然也包括你自己&#xff01;....世界消失了&#xff0c;我会在天堂爱你.如果你走了&#xff0c;我会在泪水中…

Linux C语言实现ls -l

Linux下C语言实现ls -l功能 宗旨&#xff1a;技术的学习是有限的&#xff0c;分享的精神是无限的。 需求&#xff1a;用ls -l显示文件夹下所有的文件及属性 分析&#xff1a;1 用ls显示文件夹下的所有文件&#xff0c;首先用opendir打开文件夹&#xff0c;再用readdir读取…

回答一个微信好友的创业问题

ps:很喜欢这种有烟火气息的照片— — 提问&#xff1a;我最近要创业&#xff0c;打算跟一个朋友合伙&#xff0c;但是我朋友不会技术&#xff0c;所以他只投入钱&#xff0c;也不会参与公司的管理。我们启动资金是10万&#xff0c;他打算投入7万&#xff0c;想占股65%。因为没有…

百度深度学习初级认证——已过

开头先放图&#xff0c;百度深度学习初级工程师认证已通过&#xff0c;记录一下备战和考试细节&#xff01;&#xff01;&#xff01; 1.报考 当时是通过百度的AI Studio看到深度学习的认证了&#xff0c;价格是800&#xff0c;然后阴差阳错从百度技术学院的链接看到深度学习…

Windows Mobile开发资源相关下载收录

最近收集了些关于Windows Mobile开发必备工具。以下资源完全是自己下载过的&#xff0c;直接从迅雷下载页面拷贝过来的地址。链接应该没问题的。 Windows Mobile 6 Professional SDK Refresh.msihttp://www.microsoft.com/downloads/info.aspx?na46&p1&SrcDisplayLang…

数值计算(Python实现)(一)

数值计算&#xff08;Python实现&#xff09;&#xff08;一&#xff09; 本篇内容简介&#xff1a; 解线性方程组&#xff1a;高斯消元法和高斯列主元消去法解线性方程组的迭代方法&#xff1a;雅克比&#xff08;Jacobi&#xff09;迭代法与高斯&#xff0d;赛德尔迭代法拉格…

哦,这是桶排序

漫画&#xff1a;什么是桶排序&#xff1f;要了解桶排序之前&#xff0c;可以先看看上面小灰的那篇文章&#xff0c;我觉得是比较不错的。桶排序也可以理解为分类排序&#xff0c;把不同的数据归类&#xff0c;归类之后再重新排序&#xff0c;每个桶里面的内容就是一类数据&…

LinuxC高级编程——进程

LinuxC高级编程——进程 宗旨&#xff1a;技术的学习是有限的&#xff0c;分享的精神是无限的。 每个进程在内核中都有一个进程控制块&#xff08; PCB&#xff09;来维护进程相关的信息&#xff0c; Linux内核的 进程控制块是task_struct结构体。PCB包含的信息&#xff1a; …

Oracle常见用法总结

近来&#xff0c;操作数据库比较多&#xff0c;总结了一下常用的语句&#xff01;&#xff01;&#xff01; &#xff08;1&#xff09;Oracle的默认用户 用户名&#xff1a;scott 密码&#xff1a; tiger 权限&#xff1a;普通用户 用户名&#xff1a…

如何防御光缆窃听

很多年前&#xff0c;人们就认识到采用铜缆传输信息很容易通过私搭电缆的方式被窃取。对于一个网络和安全管理人员来说&#xff0c;要么对铜缆采用更严格的安全防护措施&#xff0c;要么就使用光缆。因为很多人都认为光纤可以很好地防止***通过窃听手段截获网络数据。但是实际上…

Linux字符设备驱动实例

globalmem看 linux 设备驱动开发详解时&#xff0c;字符设备驱动一章&#xff0c;写的测试代码和应用程序&#xff0c;加上自己的操作&#xff0c;对初学者我觉得非常有帮助。写这篇文章的原因是因为我看了我之前发表的文章&#xff0c;还没有写过字符设备相关的&#xff0c;至…

8-[函数]-嵌套函数,匿名函数,高阶函数

1.嵌套函数 &#xff08;1&#xff09;多层函数套用 name "Alex"def change_name():name "Alex2"def change_name2():name "Alex3"print("第3层打印", name)change_name2() # 调用内层函数print("第2层打印", name)chan…

Linux C高级编程——时间编程

Linux高级编程——时间编程 宗旨&#xff1a;技术的学习是有限的&#xff0c;分享的精神是无限的。 1 时间类型 &#xff08;1&#xff09; 世界标准世界&#xff08;格林威治时间&#xff09; &#xff08;2&#xff09; 日历时间&#xff08;1970年1月1日0时&#xff09;—…

Excel——多个Sheet页合并成一个

import xlrd import pandas as pd from pandas import DataFrame from openpyxl import load_workbookexcel_name 文件路径/文件名.xlsx #表格地址表格名 wb xlrd.open_workbook(excel_name) # 获取workbook中所有的表格 sheets wb.sheet_names() # print(sheets)# 循环遍…

c语言画谢宾斯基三角形

谢宾斯基三角形是一个有意思的图形&#xff0c;&#xff08;英语&#xff1a;Sierpinski triangle&#xff09;是一种分形&#xff0c;由波兰数学家谢尔宾斯基在1915年提出,它是一种典型的自相似集。先画一个三角形&#xff0c;然后呢&#xff0c;取三角形的中点&#xff0c;组…

F-Secure Client Security 注册机

F-Secure Client Security 6.*/7.* 通用注册机&#xff1a;下载地址&#xff1a;http://files.cnblogs.com/boringlamb/Keymaker.rar听说8的beta版已经出来&#xff0c;期待正式版&Keygen :)转载于:https://www.cnblogs.com/boringlamb/archive/2008/04/07/1140540.html

进程间的通信——无名管道

进程间的通信——无名管道 宗旨&#xff1a;技术的学习是有限的&#xff0c;分享的精神是无限的。 一、进程间的通信 &#xff08;1&#xff09;同主机进程间数据交互机制&#xff1a;无名管道&#xff08;PIPE&#xff09;&#xff0c;有名管道&#xff08;FIFO&#xff09;…

sklearn官网-多分类问题

sklearn实战-乳腺癌细胞数据挖掘&#xff08;博主亲自录制视频&#xff09; https://study.163.com/course/introduction.htm?courseId1005269003&utm_campaigncommission&utm_sourcecp-400000000398149&utm_mediumshare 1.12.6. Multioutput classification Mult…

剖析C语言是如何画出这样的三角形的

哈哈&#xff0c;就是喜欢这些有意思的C语言上篇文章是这样写的c语言画谢宾斯基三角形那篇文章写的有点不直接&#xff0c;然后再查了下资料&#xff0c;看到了下面这些&#xff0c;我觉得解释更加好&#xff0c;这里主要是运用了光栅法&#xff0c;至于光栅法&#xff0c;可以…