首页 > 系统相关 >Linux多线程06-线程取消

Linux多线程06-线程取消

时间:2023-06-26 09:00:36浏览次数:56  
标签:main 06 取消 pthread include 线程 child 多线程

pthread_cancel

描述:

pthread_cancel()函数向线程thread发送一个取消请求。目标线程对取消请求的响应取决于该线程控制的两个属性:其取消状态和类型。

一个线程的取消状态由pthread_setcancelstate(3)确定,可以启用(对于新线程而言是默认的)或禁用。如果一个线程已禁用取消,则取消请求会保留在队列中,直到线程启用取消。如果一个线程已启用取消,则其取消类型决定了何时进行取消。

线程的取消类型由pthread_setcanceltype(3)确定,可以是异步或延迟(对于新线程而言是默认的)。异步可取消性意味着线程可以随时被取消(通常是立即的,但系统不保证这一点)。延迟可取消性意味着取消将延迟到线程下次调用的函数是取消点。取消点的函数列表在pthreads(7)中提供。

取消点

POSIX.1 指定了某些函数必须成为取消点,而某些其他函数则可能成为取消点。如果一个线程可被取消,其取消类型为延迟类型,而该线程有一个挂起的取消请求,则当该线程调用一个是取消点的函数时,该线程将被取消。

当一个取消请求被执行时,对于线程(按照以下顺序)会发生以下步骤:

  1. 取消清理处理程序会被弹出(按照它们被推入的相反顺序)并调用。(参见 pthread_cleanup_push(3)。)
  2. 线程特定数据析构器按照未指定的顺序调用。(参见 pthread_key_create(3)。)
  3. 线程被终止。(参见 pthread_exit(3)。)

上述步骤与 pthread_cancel() 调用异步发生;pthread_cancel() 的返回状态仅告知调用者取消请求是否已成功排队。

在已终止的已取消线程之后,使用 pthread_join(3) 进行线程连接会获得 PTHREAD_CANCELED 作为线程的退出状态。(连接线程是知道取消已完成的唯一方法。)

#include <pthread.h>
int pthread_cancel(pthread_t thread);
    功能: 取消线程(让线程终止)
            取消某个线程,可以终止某个线程运行,但不是立刻终止;
            而是当子线程执行到一个取消点, 线程才会终止
            取消点: 系统规定的一些系统调用, 
            可以粗略理解为从用户区到内核区的切换, 这个位置成为取消点

Compile and link with -pthread.

示例代码

#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

void* callback(void* arg){
    printf("child thread id: %ld\n",pthread_self());

    int i = 0;
    for(; i<5; i++){
        printf("child: %d\n", i); //取消点
    }

    return NULL;
}

int main(){
    pthread_t tid;
    int ret = pthread_create(&tid, NULL, callback, NULL);
    if(ret!=0){
        char* errstr = strerror(ret);
        printf("error_create: %s\n",errstr);
    }
    
    int i = 0;
    for(; i<5; i++){
        printf("main: %d\n", i);
    }

    //输出主线程和子线程ID
    printf("tid: %ld, main thread id: %ld\n",tid,pthread_self());

    //取消线程 
    pthread_cancel(tid); //子线程还没执行完就结束了

    pthread_exit(NULL);

    return 0;
}

运行

main: 0
main: 1
main: 2
main: 3
main: 4
tid: 140533913827072, main thread id: 140533922215744
child thread id: 140533913827072
child: 0
child: 1
child: 2
child: 3
child: 4

标签:main,06,取消,pthread,include,线程,child,多线程
From: https://www.cnblogs.com/anqwjoe/p/17504444.html

相关文章

  • Linux多线程05-线程的分离
    pthread_detach描述:pthread_detach()函数将由thread标识的线程标记为已分离。当一个分离的线程终止时,它的资源会自动释放回系统,而不需要另一个线程与已终止的线程加入。尝试分离一个已经分离的线程会导致未指定的行为。#include<pthread.h>intpthread_detach(pthread_tt......
  • Linux多线程08-线程同步
    一个多线程售票示例://三个窗口,共100张票#include<stdio.h>#include<pthread.h>#include<unistd.h>inttickets=100;//所有线程都共享这100张票void*sellticket(void*arg){//卖票while(tickets>0){usleep(6000);//间隔6000微秒p......
  • 2023-06-25 uview组件Vtabs 垂直选项卡无法滑动位移
    前言:uni项目中导入uview的vtabs插件来做分页,奈何导入demo后发现无法实现滑动页面来自动选中左侧菜单。原因:大哥!请先看文档,文档里有写,设置chain为true即可左右联动!好吧,是我没留意。解决方案:设置vtabs属性chain为true,官网示例代码:<template><viewclass="content">......
  • 2023-06-25 Cannot find module 'uview-ui'
    前言:把uview2.0版本通过hx导入插件方式引入项目中,运行,遂报错:Cannotfindmodule'uview-ui'==》无法找到模块'uview-ui' 检查项目下载的包,'uview-ui'已存在,并存放于uni_modules文件夹中,引入代码为://main.js,注意要在use方法之后执行importuViewfrom"uview-ui";Vue.use(......
  • 2023-06-25 SassError: Undefined variable: "$u-bg-color".
    前言:项目引入uview,使用uview的image组件时,报错:20:55:49.932SassError:Undefinedvariable:"$u-bg-color".20:55:49.937online255ofD:\project\mall-uni\uni_modules\uview-ui\components\u-image\u-image.vue20:55:49.938>>$u-image-error......
  • 异步注解@Async使用自定义线程池
    1.@Async注解@Async是java中一个注解,其作用就是加上该注解的类或方法能够异步执行任务,该注解添加到方法上时,表示该方法是异步方法,添加到类上时,表示该类中的所有方法都是异步方法。该注解的代码为:可以看出其是作用在类和方法上,能够在运行时被获取到。当在使用@Async时,如果不指......
  • 2023-06-25:redis中什么是缓存穿透?该如何解决?
    2023-06-25:redis中什么是缓存穿透?该如何解决?答案2023-06-25:缓存穿透缓存穿透指的是查询一个根本不存在的数据,在这种情况下,无论是缓存层还是存储层都无法命中。因此,每次请求都需要访问数据库,这将导致不存在的数据每次都需要查询存储层,这样缓存就失去了保护后端存储的作用。缓存穿透......
  • 2023-06-25:redis中什么是缓存穿透?该如何解决?
    2023-06-25:redis中什么是缓存穿透?该如何解决?答案2023-06-25:缓存穿透缓存穿透指的是查询一个根本不存在的数据,在这种情况下,无论是缓存层还是存储层都无法命中。因此,每次请求都需要访问数据库,这将导致不存在的数据每次都需要查询存储层,这样缓存就失去了保护后端存储的作用。缓存......
  • QT为什么只能由主线程操作UI
    QT为什么只能由主线程操作UI背景QT中,每次子线程去更新Ui都要通过信号槽去刷。其实不光是QT,很多GUI程序框架都是这么规定的。主线程:主线程是唯一允许创建QApplication或者QCoreApplication对象的,并且调用exec()启动事件循环的线程。原因直接原因:UI线程负责和用户交互,因此不能......
  • Java多线程-Lesson02
    一.Lamda表达式λ是希腊字母表的第十一位字母,英文名是LambdaLamda表达式的出现主要是为了避免匿名内部类过多的原因,它属于函数式编程的范畴 为什么要使用Lamda表达式?避免匿名内部类定义过多可以让你的代码看起来很简洁去掉了没有意义的代码,只留下一堆核心逻辑主要使用在......