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++程序示例理解设计模式中的外观模式

    一、设计模式中的外观模式 定义: 外观模式(Facade Pattern)提供了一个统一的接口,用来访问子系统中的一群接口。其目的是简化子系统的使用,消除客户端和子系统之间的耦合,让子系统内部的模块更容易维护和扩展。 要点:  外观模式不暴露子系统的内部细节,仅暴露一个应用程序所需进行的操作。 外观类是客户端与子系统之前的第一层封装,对于多个子系统,客户端可…

    C 2023年5月30日
    00
  • C语言实现求解素数的N种方法总结

    C语言实现求解素数的N种方法总结 简介 本文将总结C语言实现求解素数的N种方法。素数是只能被1和本身整除的正整数,对于计算机编程而言,求解素数是一个常见的问题。本文将介绍7种解决大约从100以内寻找素数至大约1百万以内寻找素数的方法。 方法一:暴力枚举 对于一个数n,从2开始枚举到sqrt(n)为止,判断n是否能被2~sqrt(n)中的任一数整除。如果n不能…

    C 2023年5月22日
    00
  • C语言编程中常见的五种错误及对应解决方案

    C语言编程中常见的五种错误及对应解决方案 C语言作为一门古老而广泛应用的编程语言,因为其高效、灵活、强大的特性受到了广泛的关注和使用。但是,在编写C程序时,常常会遇到各种错误,本文将介绍C语言编程中常见的五种错误及对应的解决方案,以帮助读者更好地避免这些错误并提高编程能力。 1. 语法错误(Syntax Error) 语法错误指在编译程序时发生的错误,通常是…

    C 2023年5月23日
    00
  • 如何判断一个数是否为4的幂次方?若是,并判断出来是多少次方?

    要判断一个数是否为4的幂次方,可以有以下两种方法: 方法一:使用数学公式进行判断 如果一个正整数n是4的幂次方,那么它可以表示为: n = 4^k 其中k为非负整数。我们可以对n进行以下的操作: 若n为1,则返回true。 若n mod 4不为0,则返回false,因为4的幂次方必定是4的倍数。 对n除以4,得到一个新的数,用同样的方法判断,直到最终结果为1…

    C 2023年5月23日
    00
  • 指针进阶2 – 指针和函数

    1. 函数指针 函数名 VS &函数名 对于数组而言,数组名=首元素地址,&数组名=整个数组的地址 那么函数名和&函数名等于什么 #include <stdio.h> void test() { ; } int main() { test(); printf(“%p\n”, test); printf(“%p\n”, &a…

    C语言 2023年4月18日
    00
  • 在Linux系统上进行openmp多线程编程的方法

    在Linux系统上进行OpenMP多线程编程的方法如下: 1. 安装OpenMP库和编译器 在Linux系统中使用OpenMP多线程编程需要安装OpenMP库和编译器。在大多数Linux系统上,OpenMP库和编译器可以通过包管理工具安装。例如,在Ubuntu系统中,可以通过以下命令安装: sudo apt-get install libomp-dev g+…

    C 2023年5月22日
    00
  • 原生js调用json方法总结

    当我们需要使用JSON格式的数据时,使用JavaScript原生的JSON API来处理数据是非常常见的。在本篇文档中,我们将会全面介绍如何原生JS调用JSON方法。 JSON简介 JSON (JavaScript对象表示法) 是一种用于将数据存储和交换的文本格式。JSON 派生自JavaScript语言,但是JSON 格式是语言无关的。 JSON是一种非常…

    C 2023年5月23日
    00
  • C语言设计前中后队列实例代码

    C语言设计前中后队列实例代码攻略 在本篇文章中,我们将学习如何在C语言中设计前、中、后队列,并提供相应的示例代码。下面将分别对前、中、后队列进行介绍和说明。 前队列 前队列,也称为顺序队列。它是一种数据结构,它具有先进先出(First in First Out,简称FIFO)的特点,是一种简单但基本的数据结构,常用在队列缓存、消息队列、web服务器等领域。下…

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