当前位置: 首页 > news >正文

用户态 kill 与 pthread_kill 的区别?

在 Linux 用户态中,pthread_killkill 都能发送系统信号,但它们的作用对象、使用场景和行为有显著区别,核心差异在于信号的接收者不同

1. 作用对象不同

  • kill(pid_t pid, int sig)
    用于向 进程 发送信号,pid 参数指定目标进程的 ID:
    • pid > 0:向 ID 为 pid进程发送信号
    • pid = 0:向当前进程所在进程组的所有进程发送信号
    • pid = -1:向系统中所有有权限发送的进程发送信号(特殊权限下)
    • pid < -1:向进程组 ID 为 |pid| 的所有进程发送信号
  • pthread_kill(pthread_t thread, int sig)
    用于向 同一进程内的特定 线程 发送信号,thread 参数是目标线程的 ID(由 pthread_create 返回)。

2. 信号的处理范围不同

  • kill 发送的信号:属于进程级信号,默认由进程内的 “主线程” 或 “任意线程” 处理(取决于信号处理函数的注册方式)。
    例如,若进程中注册了 SIGINT 的处理函数,用 kill 向该进程发送 SIGINT,会触发进程内的该处理函数(由内核选择一个线程执行)。
  • pthread_kill 发送的信号:属于线程级信号,专门针对指定线程,信号处理函数在目标线程的上下文中执行。
    例如,向 ‘线程 A’ 发送 SIGUSR1,若该信号已注册处理函数,则处理函数在 ‘线程 A’ 中运行。

3. 特殊信号的行为差异

  • 对于会导致进程终止的信号(如 SIGKILLSIGTERM):
    • 无论用 kill 还是 pthread_kill 发送,最终都会导致整个进程终止(因为线程是进程的一部分,进程终止会带动所有线程终止)。
    • 区别在于:kill 直接针对进程,pthread_kill 虽指定线程,但信号的 “终止进程” 语义会作用于整个进程。
  • 对于可捕获的信号(如 SIGUSR1SIGALRM):
    • kill 发送的信号可能被进程内任意线程捕获(内核调度决定)。
    • pthread_kill 发送的信号只会被目标线程捕获(如果该线程未阻塞此信号)。

4. 使用场景不同

  • kill 的典型场景
    进程间通信,例如:
    • 终端通过 kill 向后台进程发送 SIGTERM 要求其退出
    • 父进程向子进程发送信号控制其行为
  • pthread_kill 的典型场景
    同一进程内的线程间通信,例如:
    • 主线程向阻塞的子线程发送信号,中断其阻塞状态(如从 sleepwait 中唤醒)
    • 通知特定线程处理某个事件

示例对比

#include <stdio.h>
#include <pthread.h>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>// 信号处理函数
void sig_handler(int sig) {printf("信号 %d 在线程 %lu 中被处理\n", sig, pthread_self());
}// 子线程函数
void *thread_son_func(void *arg) {printf("子线程 %lu 启动\n", pthread_self()); //与ps -T -p <PID>得到的线程ID无关,这样打印也不太规范while (1) {sleep(1); // 模拟阻塞}return NULL;
}int main() {signal(SIGUSR1, sig_handler); // 注册信号处理函数pthread_t tid;pthread_create(&tid, NULL, thread_son_func, NULL);sleep(1); //给线程创建留点时间// 用 pthread_kill 向 "子线程" 发送信号pthread_kill(tid, SIGUSR1); // 信号在子线程中处理sleep(1); //给信号中打印留点时间// 用 kill 向当前 "进程" 发送信号(可能被任意线程处理)kill(getpid(), SIGUSR1); // 信号可能在主线程或子线程中处理pthread_join(tid, NULL);return 0;
}

输出可能为:

子线程 140610751647488 启动
信号 10 在线程 140610751647488 中被处理  // pthread_kill 发送,子线程处理
信号 10 在线程 140610759944576 中被处理  // kill 发送,主线程处理(可能不同)

总结

特性killpthread_kill
接收者进程(或进程组)同一进程内的特定线程
信号处理上下文进程内任意线程(内核决定)目标线程本身
主要用途进程间信号通信同一进程内线程间信号通信
对进程的影响可能终止整个进程(如 SIGKILL同左(信号语义决定,与线程无关)

简单说:kill 是 “给进程发信号”,pthread_kill 是 “给进程内的某个线程发信号”。

http://www.dtcms.com/a/360452.html

相关文章:

  • 动态链表:结构体模拟单链表的终极指南
  • ts 定义类型
  • Linux学习:简单模拟实现C++中的线程类
  • C++算法学习专题:前缀和
  • 【Linux网络编程】应用层协议-----HTTP协议
  • PostgreSQL表膨胀的危害与解决方案
  • More Effective C++ 条款19:理解临时对象的来源(Understand the Origin of Temporary Objects)
  • centos 7 安装docker、docker-compose教程
  • AI 编程新玩法:用 yunqi-saas-kit 框架制作小游戏,看广告变现轻松赚钱​
  • 国产数据库之TiDB:博采众长
  • Ruoyi-vue-plus-5.x第二篇MyBatis-Plus数据持久层技术:2.2 分页与性能优化
  • [嵌入式embed]Keil5项目提示Missing: Compiler Version 5
  • 工业互联项目总结:UART
  • Backroom:信息代币化 AI 时代数据冗杂的解决方案
  • 漏洞基础与文件包含漏洞原理级分析
  • 使用 Python mlxtend库进行购物篮分析、关联规则
  • 软考中级习题与解答——第一章_数据结构与算法基础(3)
  • 进程状态 —— Linux内核(Kernel)
  • Linux 文件夹权限也会导致基本命令权限缺失问题
  • 【学Python自动化】 5. Python 数据结构学习笔记
  • postman带Token测试接口
  • 打工人日报#20250831
  • LangChain核心抽象:Runnable接口深度解析
  • * 和**有时展开,有时收集。*在对可迭代对象展开 **对字典展开。一般只看收集就够了,在函数定义的时候传入参数用
  • 第二十七天-ADC模数转换实验
  • linux系统学习(12.linux服务)
  • 【星闪】Hi2821 | SPI串行外设接口 + OLED显示屏驱动例程
  • 语音芯片3W输出唯创知音WTN6040FP、WT588F02BP-14S、WT588F04AP-14S
  • [回溯+堆优化]37. 解数独
  • Q1 Top IF 18.7 | 基于泛基因组揭示植物NLR进化