C语言如何正确的终止正在运行的子线程

C语言中,终止正在运行的子线程有两种常用方法:一种是让线程函数正常返回;另一种是使用pthread_cancel函数强制终止线程。我们来分别介绍这两种方法的具体实现。

方法一

让子线程函数正常返回,从而终止子线程的执行。这种方式需要在线程函数中判断是否需要退出,并在需要退出时,将线程函数的返回值设为0。线程启动时,使用pthread_create函数创建线程,并将线程ID存储在一个全局变量中,以便在需要终止线程时调用pthread_cancel函数。

下面是一个示例代码,使用while循环不断执行某些任务,在接收信号后退出线程:

#include <stdio.h>
#include <pthread.h>
#include <signal.h>

pthread_t tid;

void signal_handler(int sig) {
    if (sig == SIGINT) {
        printf("SIGINT received, canceling thread...\n");
        pthread_cancel(tid);
    }
}

void *thread_func(void *arg) {
    int count = 0;
    while (1) {
        printf("Task %d is running...\n", count++);
        sleep(1);
    }
    return NULL; // 线程函数返回值为NULL,表示正常退出
}

int main() {
    signal(SIGINT, signal_handler);
    pthread_create(&tid, NULL, thread_func, NULL);
    pthread_join(tid, NULL); //等待线程结束,这行就是可有可无的,其实加上这行,只是为了好看
    return 0;
}

不断输出任务,并在接收信号后退出线程,注意:有一个重要的点,在主线程中需要调用pthread_join函数,等待子线程结束,这样才能使子线程占用的资源被正确释放。如果不等待子线程结束而直接返回,子线程就会成为“僵尸线程”,占用系统资源。

方法二

使用pthread_cancel函数强制终止子线程的执行。pthread_cancel函数调用后,线程会收到一个取消请求,可以使用pthread_setcancelstate函数在线程函数中判断是否接收到了取消请求,并进行相应的处理。

下面是一个示例代码,使用while循环不断执行某些任务,在接收信号后强制终止线程:

#include <stdio.h>
#include <pthread.h>
#include <signal.h>

pthread_t tid;

void signal_handler(int sig) {
    if (sig == SIGINT) {
        printf("SIGINT received, canceling thread...\n");
        pthread_cancel(tid);
    }
}

void *thread_func(void *arg) {
    int cancel_state;
    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); // 允许取消

    while (1) {
        pthread_testcancel(); // 检查是否接收到取消请求,如果是则终止线程
        printf("Task is running...\n");
        sleep(1);
    }
    return NULL;
}

int main() {
    signal(SIGINT, signal_handler);
    pthread_create(&tid, NULL, thread_func, NULL);
    pthread_join(tid, NULL); // 等待线程结束

    return 0;
}

每次任务执行完成后,调用pthread_testcancel函数检查线程是否收到了取消请求。如果收到了,则线程通知取消,线程函数就会返回NULL。需要注意的是,即使线程通过pthread_testcancel函数检查取消请求时,没有收到取消请求,函数也会立刻返回。

参考文献:
- Linux系统编程
- POSIX多线程编程指南

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言如何正确的终止正在运行的子线程 - Python技术站

(0)
上一篇 2023年5月23日
下一篇 2023年5月23日

相关文章

  • C语言栈顺序结构实现代码

    下面我将详细讲解如何用 C 语言实现栈的顺序结构并提供两个示例。 什么是栈? 栈是一种数据结构,特点是 Last In First Out (LIFO) 后进先出。栈具有两个基本操作:压入(push)和弹出(pop)。在栈的顺序结构中,栈被定义为一个固定大小的数组,其中有一个指针(top)指向栈的顶部元素。 栈的顺序结构实现 首先,我们需要定义栈的数据结构,…

    C 2023年5月23日
    00
  • 支付宝二面:使用 try-catch 捕获异常会影响性能吗(推荐)

    当我们编写程序时,难免会遇到一些异常情况,比如输入的参数不符合要求,文件不存在等等。为了防止程序发生崩溃,我们通常会使用 try-catch 语句来捕获异常。但是有些人认为,使用 try-catch 语句会影响程序的性能。那么,这种说法是否正确呢? 在实际开发中,使用 try-catch 语句捕获异常是一种很常见的做法。虽然在异常发生时会产生一定的性能损耗,…

    C 2023年5月23日
    00
  • 使用C++ MFC编写一个简单的五子棋游戏程序

    使用C++ MFC编写五子棋游戏程序需要遵循一定的步骤: 创建MFC应用程序工程:使用Visual Studio创建空的MFC应用程序,并确定目标平台、字符集、应用程序类型等基本设置。 设计窗口UI:在资源视图中添加对话框资源,并设计出游戏界面,包括棋盘、落子点、游戏状态等。 编写对话框类:在对话框类中添加游戏逻辑处理函数,并在OnLButtonDown等消…

    C 2023年5月23日
    00
  • 详解C++中的const关键字及与C语言中const的区别

    详解C++中的const关键字及与C语言中const的区别 const 基础知识 在 C++ 中,const 关键字表示“常量”,即标识符被定义为只读的,不可修改的量。定义常量的格式如下: const <type> <name> = <value>; 其中,<type> 可以是任何 C++ 数据类型,<n…

    C 2023年5月23日
    00
  • Android使用jni调用c++/c方法详解

    Android使用Jni调用C++/C方法详解 什么是JNI? JNI全称Java Native Interface,就是Java本地接口,它可以让Java程序调用其他语言编写的动态库,比如C++、C语言等。 Jni调用C++/C方法步骤 准备好动态库。在使用Jni调用C++/C方法之前,首先需要编写好被调用的C++/C代码,并将其编译成动态库。在编译完成后…

    C 2023年5月23日
    00
  • 实例解析js中try、catch、finally的执行规则

    下面是详细讲解“实例解析js中try、catch、finally的执行规则”的攻略。 一、try、catch、finally的基本概念 在JavaScript中,有时我们需要捕获程序执行中的异常信息,同时在出现异常时进行后续处理。这时候我们就需要用到try、catch和finally语句。 try块用于捕获可能引发异常的代码块。 catch块用于处理try块…

    C 2023年5月23日
    00
  • Vue.js实现的计算器功能完整示例

    下面我会详细讲解Vue.js实现的计算器功能完整示例的攻略。 准备工作 在开始实现计算器之前,需要在HTML文件中引入Vue.js和一个CSS文件。 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Vue C…

    C 2023年5月22日
    00
  • 如何在抖音卖课程?在抖音上卖课程方式汇总

    如何在抖音卖课程? 要在抖音上卖课程,以下步骤值得一试: 步骤一:申请店铺账号 想要在抖音上卖课程,首先需要注册店铺账号并认证。 1.进入抖店(抖音商家后台),根据提示注册店铺账号。 2.填写相关信息,提交认证材料。 步骤二:准备课程内容 在抖音上卖课程需要有足够的课程内容,要为用户提供有价值的学习体验。 1.根据目标用户和市场需求,确定课程内容、形式等。 …

    C 2023年5月22日
    00
合作推广
合作推广
分享本页
返回顶部