如何正确处理pthread_kill调用实现线程与程序正常退出
问题成因
pthread_kill本质是向指定线程ID发送信号,而非直接终止线程。如果你发送的SIGVTALRM信号没有对应处理函数,触发的默认行为是终止整个进程,两种情况的差异来源如下:
- 保留
sleep(1)时:1秒的等待时间足够子线程完成全部逻辑执行并退出,此时你传入pthread_kill的thread_id已经是无效ID,调用会直接返回错误码,不会实际发送信号触发终止逻辑,因此看起来程序正常退出。 - 注释
sleep(1)时:pthread_create返回仅代表线程ID分配成功,不代表线程已经启动运行,此时调用pthread_kill大概率命中还在运行的子线程,信号触发默认终止行为,所以进程被系统杀死提示killed。
正确实现方案
要满足「调用pthread_kill时线程已经创建并处于运行状态」的诉求,不要依赖不可靠的sleep等待,用同步机制实现线程间的状态确认即可,同时要为信号注册处理函数避免进程被异常终止,完整实现逻辑如下:
- 先为目标信号注册自定义处理函数,覆盖默认的进程终止行为
- 用屏障/条件变量等同步组件,确保主线程发送信号前,子线程已经进入运行状态
- 最后调用
pthread_join回收线程资源,避免僵尸线程
示例代码
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <pthread.h> #include <signal.h> // 全局屏障用于同步主线程和子线程的启动状态 pthread_barrier_t barrier; // SIGVTALRM信号自定义处理函数 void sig_handler(int sig) { // 这里写你收到信号后的自定义处理逻辑,比如设置线程退出标记 printf("Thread received SIGVTALRM\n"); } void *mythread(void *vargp) { // 线程启动后先触发屏障同步,通知主线程我已经处于运行状态 pthread_barrier_wait(&barrier); printf("Printing from Thread \n"); // 业务逻辑省略 printf("End of thread\n"); return NULL; } int main() { pthread_t thread_id; printf("main start\n"); // 初始化屏障,计数为2:主线程和子线程各触发一次wait就放行 pthread_barrier_init(&barrier, NULL, 2); // 注册信号处理函数 signal(SIGVTALRM, sig_handler); pthread_create(&thread_id, NULL, mythread, NULL); // 等待屏障触发,返回时说明子线程已经进入运行状态 pthread_barrier_wait(&barrier); // 此时可以安全调用pthread_kill pthread_kill(thread_id, SIGVTALRM); // 等待子线程执行完成回收资源 pthread_join(thread_id, NULL); // 销毁同步资源 pthread_barrier_destroy(&barrier); return 0; }
如果不想用屏障,也可以用互斥量+条件变量+状态标记的组合实现同步,本质都是保证线程状态的可靠确认,不会出现时间窗口问题。
内容的提问来源于stack exchange,提问作者Learner09
相关产品推荐
相关产品推荐

