#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;}
#include <stdio.h>#include <pthread.h>#include <stdlib.h>#include <sys/types.h>#include <unistd.h>int times = 1;// 先打印再申请内存空间void* func(void* arg) {printf("times = %d\n", times);times++;char s[1 << 20]; // 申请 1MB 内存空间(分配在栈空间上)func(NULL);return NULL;}int main() {pthread_t t;pthread_create(&t, NULL, func, NULL);pthread_join(t, NULL);return 0;}
经验总结扩展阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 2023年1月29日艾灸吉日一览表 2023年1月29日适合艾灸吗
- 2023年9月17日上学吉日一览表 2023年9月17日是上学吉日吗
- 2023年1月29日洗澡好吗 2023年1月29日洗澡吉日一览表
- 2023年1月29日剪头发行吗 2023年1月29日剪头发吉日一览表
- 2023年1月29日分居行吗 2023年1月29日分居好不好
- 2023年9月17日训马吉日一览表 2023年9月17日适合训马吗
- 2023年9月17日搭窝吉日一览表 2023年农历八月初三宜搭窝吗
- 2023年9月17日制作猫窝黄道吉日 2023年9月17日制作猫窝吉日一览表
- 2023年1月29日给佛像开光吉日一览表 2023年1月29日给佛像开光行吗
- 2023年1月29日玉石开光好吗 2023年1月29日玉石开光吉日一览表