线程终止的4种方式

时间:2025-11-01  作者:Diven  阅读:0

示例 demo

最简单的 demo:

线程终止的4种方式

statIC voidthread1_func(void *arg){    int i = 0;    // able to be cancel    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);    pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);    for(i=0; ; i++) {        printf("thread1 %d", 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 thread1    pthread_join(t, &res);      // wait thread1    if (res == PTHREAD_CANCELED)        printf("thread1 was terminate by cancel");    else        printf("thread1 was not terminate by cancel");    exit(EXIT_SUCCESS);}

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

运行效果:

thread1 0thread1 1thread1 2thread1 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 pthreads  Cancellation 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 线程终止
    审核编辑 :李倩


 


猜您喜欢

电子元器件领域,选择合适的贴片电阻厂家很重要。这不仅关系到产品的质量和性能,也直接影响到项目的成本和进度。为了帮助您快速找到可靠的合作伙伴,我们整理了一份贴片电...
2024-11-29 10:26:01

熔断器作为保护电路安全的重要元件,越来越受到重视。LIANG MENG(亮盟)作为知名的照明熔断器品牌,优异的性能和的应用赢得了市场的认可。本文将详细介绍LIA...
2021-03-18 08:03:30

在现代工业和制造业中,排母作为重要的连接器件,应用于电子产品、机械设备等领域。那么,排母的规格尺寸究竟是多少呢?排母的规格尺寸通常以针脚数和间距来划分。常见的针...
2011-04-16 00:00:00

呼气分析因其非侵入性和易于实时监测而成为一种很有前景的医学诊断方法。呼气中的某些挥发性有机化合物(VOC)被认为是特定疾病的潜在生物标志物。以纳米材料为传感界面...
2023-11-17 09:30:00

FPGA项目开发之同步信号和亚稳态让我们从触发器开始,所有触发器都有一个围绕活动时钟沿的建立(setup time)和保持窗口(hold time),在此期间...
2022-10-18 09:47:00

x7r电容器是电子元器件中常见的。具有良好的性能和稳定性。本文将介绍x7r电容器的作用,帮助大家更好地理解。主要作用x7r电容器主要用于存储电能。能在电路中平稳...
2025-03-24 05:31:39

你或许从未听说过DC-DC控制器,但却默默地支撑着我们生活中几乎所有电子设备的运作。从智能手机到笔记本电脑,从电动汽车到航空航天设备,DC-DC控制器都是重要的...
2024-01-02 00:00:00

排阻作为电路设计中的重要元件,其性能参数受到关注。风华高科(FH)作为国内知名的电子元器件制造商,其排阻产品以优良的品质和稳定的性能获得了认可。本文将围绕“FH...
2016-05-22 02:43:30

合金电阻因其优异的性能被应用于各种电子设备中。作为行业内知名品牌,宇阳(EYANG)合金电阻凭借其稳定的品质和丰富的规格,赢得了众多客户的青睐。本文将详细介绍宇...
2015-10-22 23:33:10

SO14_150MIL是在电子元器件领域应用的标准,主要涉及到半导体封装的尺寸和规格。随着科技的进步和电子设备的不断发展,SO14_150MIL的应用越来越受到...
2025-04-26 14:01:44