【线程】注意的几个问题。
- pthread_kill可以判断一个线程是否退出--Demo程序
- 在使用pthread_cancel去结束线程时,被结束线程函数不能有返回值,即在发送cancel指令时,线程必须是live的状态。否则会产生“段错误”
- pthread_cancel并不能立即退出线程(实测必须进行延时即可退出线程),发送cancel指令成功后,必须使用pthread_join去等待退出线程。
- 使用pthread_join时,线程属性必须是线程合并。
- 使用pthread_join退出线程后,不能在使用phtread_kill去判断线程是否退出,因为pthread_join退出线程后,被等待线程的资源被收回。线程的tid会被回收,所以用pthread_kill(tid)会发生"segmentation fault".
- 设置线程分离属性后,线程结束后会自动进行资源回收。
- 在没有设置线程属性时,默认线程合并。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | #include<stdio.h> #include <pthread.h> #include <stdlib.h> #include <pthread.h> #include <unistd.h> #include <errno.h> #include <signal.h> void *func1() /*1秒钟之后退出*/ { pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); //allow to exit thread pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); //set thread canncel immediately printf ( "pthread1(ID:0x%x)。\n" ,(unsigned int )pthread_self()); while (1) { } //pthread_exit((void *)0); } void *func2() /*5秒钟之后退出*/ { pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); //allow to exit thread pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); //set thread canncel immediately printf ( "pthread2(ID:0x%x)。\n" ,(unsigned int )pthread_self()); while (1); // printf("pthread2(ID:0x%x)exit。\n",(unsigned int)pthread_self()); // pthread_exit((void *)0); return NULL; } void test_pthread(pthread_t tid) /*pthread_kill的返回值:成功(0) 线程不存在(ESRCH) 信号不合法(EINVAL)*/ { int pthread_kill_err; pthread_kill_err = pthread_kill(tid,0); if (pthread_kill_err == ESRCH) printf ( "ID 0x%x is not exist。\n" ,(unsigned int )tid); else if (pthread_kill_err == EINVAL) printf ( "signal 。\n" ); else printf ( "ID 0x%x live pthread_kill_err=%d。\n" ,(unsigned int )tid,pthread_kill_err); } int main() { int ret; pthread_t tid1,tid2; pthread_attr_t attr; pthread_attr_init(&attr); pthread_create(&tid1,&attr,func1,NULL); pthread_create(&tid2,&attr,func2,NULL); sleep(3); /*创建两个进程3秒钟之后,分别测试一下它们是否还活着*/ if (!pthread_cancel(tid1)) { pthread_join(tid1, NULL); printf ( "pthread 1 cancel OK\n" ); } if (!pthread_cancel(tid2)) { pthread_join(tid2, NULL); printf ( "pthread 2 cancel OK\n" ); } // sleep(1);//发送cancel指令后,延时可以结束线程。如果不使用延时,则使用pthread_join来阻塞结束(pthread_join的方法) test_pthread(tid1); /*测试ID为tid1的线程是否存在*/ test_pthread(tid2); /*测试ID为tid2的线程是否存在*/ exit (0); } |
分类:
linux操作系统
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通