- PTHREAD_CANCEL_DEFERRED:当一个线程的取消状态是这个的时候,线程的取消就会被延迟执行 , 知道线程调用一个是取消点的(cancellation point)函数,比如 sleep 和 pthread_testcancel ,所有的线程的默认取消执行的类型就是这个类型 。
- PTHREAD_CANCEL_ASYNCHRONOUS:如果线程使用的是这个取消类型那么线程可以在任何时候被取消执行,当他接收到了一个取消信号的时候 , 马上就会被取消执行,事实上这个信号的实现是使用 tgkill 这个系统调用实现的 。
有了以上的知识基础我们现在可以来谈一谈前面的两个函数了:
- pthread_cancel(t) :是给线程 t 发送一个取消请求 。
- pthread_testcancel():这个函数是一个取消点,当执行这个函数的时候,程序就会取消执行 。
#include <stdio.h>#include <pthread.h>#include <assert.h>#include <unistd.h>void* task(void* arg) {while(1) {}return NULL;}int main() {void* res;pthread_t t1;pthread_create(&t1, NULL, task, NULL);int s = pthread_cancel(t1);if(s != 0) // s == 0 mean call successfullyfprintf(stderr, "cancel failed\n");pthread_join(t1, &res);assert(res == PTHREAD_CANCELED);return 0;}
在上面的代码当中我们启动了一个线程不断的去进行进行死循环的操作 , 程序的执行结果为程序不会终止 , 因为主线程在等待线程的结束 , 但是线程在进行死循环,而且线程执行死循环的时候没有调用一个是取消点的函数 , 因此程序不会终止取消 。下面我们更改程序,将线程的取消类型设置为 PTHREAD_CANCEL_ASYNCHRONOUS,在看看程序的执行结果:
#include <stdio.h>#include <pthread.h>#include <assert.h>#include <unistd.h>void* task(void* arg) {pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);while(1) {}return NULL;}int main() {void* res;pthread_t t1;pthread_create(&t1, NULL, task, NULL);int s = pthread_cancel(t1);if(s != 0) // s == 0 mean call successfullyfprintf(stderr, "cancel failed\n");pthread_join(t1, &res);assert(res == PTHREAD_CANCELED);return 0;}
在上面的程序当中我们在线程执行的函数当中使用 pthread_setcanceltype
将线程的取消类型设置成 PTHREAD_CANCEL_ASYNCHRONOUS 这样的话就能够在其他线程使用 pthread_cancel 的时候就能够立即取消线程的执行 。int pthread_setcanceltype(int type, int *oldtype)
上方是 pthread_setcanceltype 的函数签名,在前面的使用当中我们只使用了第一个参数,第二个参数我们是设置成 NULL,第二个参数我们可以传入一个 int 类型的指针,然后会在将线程的取消类型设置成 type 之前将前一个 type 拷贝到 oldtype 所指向的内存当中 。type: 有两个参数:PTHREAD_CANCEL_ASYNCHRONOUS 和 PTHREAD_CANCEL_DEFERRED。
int pthread_setcancelstate(int state, int *oldstate);
设置取消状态的函数签名和上一个函数签名差不多,参数的含义也是差不多 , type 表示需要设置的取消状态,有两个参数:PTHREAD_CANCEL_ENABLE 和 PTHREAD_CANCEL_DISABLE,参数 oldstate 是指原来的线程的取消状态,如果你传入一个 int 类型的指针的话就会将原来的状态保存到指针指向的位置 。其实关于线程的一些细节还有比较多的内容限于篇幅,在本篇文章当中主要给大家介绍这些细节 。
关于栈大小程序的一个小疑惑在上文当中我们使用了一个小程序去测试线程的栈空间的大?。⑶掖蛴『?
func
的调用次数,每一次调用的时候我们都会申请 1MB 大小的栈空间变量 。现在我们看下面两个程序 , 在下面两个程序只有 func
函数有区别,而在 func
函数当中主要的区别就是:- 在第一个程序当中是先申请内存空间,然后再打印变量
times
的值 。 - 在第二个程序当中是先打印变量
times
的值,然后再申请内存空间 。
#include <stdio.h>#include <pthread.h>#include <stdlib.h>#include <sys/types.h>#include <unistd.h>int times = 1;// 先申请内存空间再打印void* func(void* arg) {char s[1 << 20]; // 申请 1MB 内存空间(分配在栈空间上)printf("times = %d\n", times);times++;func(NULL);return NULL;}int main() {pthread_t t;pthread_create(&t, NULL, func, NULL);pthread_join(t, NULL);return 0;}
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- hush韩剧结局_hush韩剧最后一集的剧情
- 苹果xr参数配置_苹果xr参数配置详细参数
- FHQ Treap 详解
- 一 UBOOT编译--- make xxx_deconfig过程详解
- Ubuntu安装Docker及镜像加速器
- HYTHIOL-C PLUS白兔牌美白丸 吃了一个月后的反馈
- 十一 前后端分离项目:实现"删"功能(前后端)
- 七 pod:静态pod
- 夯实Java基础,一篇文章全解析线程问题
- 天猫童装店铺销量排行榜前十,巴拉巴拉童装销量第一