pthread 线程立即取消的两种方法
1.相关函数介绍
a.
int pthread_cancel(pthread_t thread)
发送终止信号给thread线程,如果成功则返回0,否则为非0值。发送成功并不意味着thread会终止。
b.
int pthread_setcancelstate(int state, int *oldstate)
设置本线程对Cancel信号的反应,state有两种值:PTHREAD_CANCEL_ENABLE(缺省)和PTHREAD_CANCEL_DISABLE,
分别表示收到信号后设为CANCLED状态和忽略CANCEL信号继续运行;old_state如果不为NULL则存入原来的Cancel状态以便恢复。
c.
int pthread_setcanceltype(int type, int *oldtype)
设置本线程取消动作的执行时机,type由两种取值:PTHREAD_CANCEL_DEFERED和PTHREAD_CANCEL_ASYNCHRONOUS,仅当Cancel状态为Enable时有效,分别表示收到信号后继续运行至下一个取消点再退出和立即执行取消动作(退出,线程以下程序不执行);oldtype如果不为NULL则存入运来的取消动作类型值。
d.
void pthread_testcancel(void)
pthread_testcancel在不包含取消点,但是又需要取消点的地方创建一个取消点,以便在一个没有包含取消点的执行代码线程中响应取消请求。
线程取消功能处于启用状态且取消状态设置为延迟状态时,pthread_testcancel()函数有效。 如果在取消功能处处于禁用状态下调用pthread_testcancel(),则该函数不起作用。
取消点:
线程取消的方法是向目标线程发Cancel信号,但如何处理Cancel信号则由目标线程自己决定,或者忽略、或者立即终止、或者继续运行至Cancelation-point(取消点),由不同的Cancelation状态决定。
pthreads标准指定了几个取消点,其中包括:
(1)通过调用pthread_testcancel()以编程方式建立线程取消点。
(2)线程等待pthread_cond_wait或pthread_cond_timewait()中的特定条件。
(3)被sigwait(2)阻塞的函数
(4)一些标准的库调用。通常,这些调用包括线程可基于阻塞的函数。
根据POSIX标准,pthread_join()、pthread_testcancel()、pthread_cond_wait()、pthread_cond_timedwait()、sem_wait()、sigwait()等函数以及
read()、write()等会引起阻塞的系统调用都是Cancelation-point
e.
int pthread_join(pthread_t thread, void **value_ptr);
thread:等待退出线程的线程号。
value_ptr:退出线程的返回值。
1.同步取消线程
代码示例:
#include<stdio.h> #include<stdlib.h> #include <pthread.h> void *thread_fun(void *arg) { int i=1; pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); /*同步取消,等到下一个取消点再取消*/ pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL); printf("thread start \n"); while(1) { i++; /*手动建立一个取消点, 防止线程中无取消点,导致线程不取消。*/ pthread_testcancel(); } return (void *)0; } int main() { void *ret=NULL; int iret=0; pthread_t tid; pthread_create(&tid,NULL,thread_fun,NULL); sleep(1); pthread_cancel(tid);//取消线程 pthread_join(tid, &ret); printf("thread 3 exit code %d\n", (int)ret); return 0; }
2.异步取消线程
示例代码:
#include<stdio.h> #include<stdlib.h> #include <pthread.h> void *thread_fun(void *arg) { int i=1; pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); /*同步取消,等到下一个取消点再取消*/ // pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL); /*异步取消, 线程接到取消信号后,立即退出*/ pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); printf("thread start \n"); while(1) { i++; } return (void *)0; } int main() { void *ret=NULL; int iret=0; pthread_t tid; pthread_create(&tid,NULL,thread_fun,NULL); sleep(1); pthread_cancel(tid);//取消线程 pthread_join(tid, &ret); printf("thread 3 exit code %d\n", (int)ret); return 0; }
代码编译:
gcc pthread_test.c -o pthread_test -lpthread
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)