Linux信号与进程间通信学习笔记

一、信号 signal

信号是内核和应用程序之间通信的机制,属于异步通知。进程收到信号,可以选择:默认处理、忽略信号、捕捉信号自定义回调函数。

常见信号速查表

信号 编号 触发来源 说明
SIGINT 2 Ctrl + c 终端中断,终止程序
SIGQUIT 3 Ctrl + \ 退出程序,会生成core转储文件
SIGKILL 9 kill -9 强制杀死进程,不能捕捉、不能忽略
SIGSEGV 11 程序异常 段错误,访问非法内存
SIGPIPE 13 管道 管道破裂,向没有读端的管道写数据
SIGALRM 14 alarm函数 定时时间到产生闹钟信号
SIGCHLD 17 子进程 子进程退出,通知父进程
SIGCONT 18 系统 恢复被暂停的进程继续运行
SIGSTOP 19 Ctrl+z 暂停进程,不能捕捉、不能忽略

⚠ 重点考点:9号SIGKILL、19号SIGSTOP,无法被捕捉、无法被忽略。

信号处理函数 signal

c 复制代码
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
  • 参数1 signum:信号编号
  • 参数2 handler 三种选择:
    1. SIG_IGN:忽略该信号
    2. SIG_DFL:系统默认处理方式
    3. 自定义函数指针:捕捉信号,执行回调函数
  • 返回值:成功返回上一次注册的处理函数;失败返回 SIG_ERR

配套工具函数

  1. pause()
c 复制代码
int pause(void);

功能:让进程睡眠阻塞,直到收到信号被唤醒。

  1. alarm()闹钟
c 复制代码
unsigned int alarm(unsigned int seconds);

seconds秒之后,内核给当前进程发送SIGALRM闹钟信号。


二、进程间通信 IPC

Linux常见IPC方式:

  1. 管道(无名管道、有名管道FIFO)
  2. 信号
  3. 消息队列
  4. 共享内存
  5. 信号量

1. 无名管道 pipe

无名管道:只适用于有亲缘关系进程通信(父子进程),内核开辟缓冲区,没有实体磁盘文件。

c 复制代码
int pipe(int pipefd[2]);
  • pipefd[0]:管道读文件描述符
  • pipefd[1]:管道写文件描述符
  • 返回:成功返回0;失败返回-1
管道行为特性(考试高频)
  1. 管道有写端

    • 缓冲区有数据:read直接读出数据
    • 缓冲区无数据:read阻塞等待,直到写入数据
  2. 管道没有写端(全部写端close)

    • 缓冲区有数据:正常读完
    • 缓冲区为空:read返回0,结束,不阻塞
  3. 管道有读端

    • 管道没写满,write直接写入
    • 管道写满,write阻塞,等待读端取走数据
  4. 管道没有读端(全部读端close)

    • 调用write写数据 → 产生SIGPIPE管道破裂信号,进程直接退出。

无名管道单向通信;父子进程各保留一端,关闭不需要的fd。

2. 有名管道 FIFO mkfifo

有名管道:无亲缘关系进程之间也可以通信,磁盘上存在管道文件,但是数据仍然存放内核缓冲区,磁盘文件只起标识作用。

c 复制代码
int mkfifo(const char *pathname, mode_t mode);
  • pathname:管道文件路径
  • mode:文件权限
  • 返回:成功0,失败-1

特性:open打开FIFO的时候,读端、写端必须同时到位,否则阻塞等待对端打开 。

只有读打开,没有写打开:读端阻塞;只有写打开没有读打开:写端阻塞。

三、无名管道 vs 有名管道对比

无名管道 pipe 有名管道 FIFO
通信进程 仅限亲缘进程(父子) 任意进程,无关进程也可以
磁盘文件 无实体文件 磁盘存在fifo特殊文件
创建方式 pipe() mkfifo()
open打开 不需要open,直接pipe拿到fd 需要open打开管道文件
打开阻塞 不会出现open阻塞 单独打开读或者写会阻塞

四、信号与管道易错考点总结

  1. SIGKILL(9)、SIGSTOP(19),不能捕捉、不能忽略。
  2. Ctrl+C → SIGINT;Ctrl+\ → SIGQUIT;Ctrl+Z → SIGTSTP。
  3. 管道没有读端,write产生SIGPIPE信号,程序崩溃。
  4. 无名管道只能父子进程;FIFO有名管道任意进程。
  5. FIFO打开必须读写两端同时存在,否则open阻塞。
  6. SIGCHLD:子进程退出通知父进程,用来处理僵尸进程。

编译提示

信号程序普通gcc编译;管道代码同样直接gcc编译,不需要额外库。

相关推荐
要开心吖ZSH8 分钟前
MySQL 慢 SQL 排查操作手册-个人笔记版
java·笔记·sql·mysql·慢查询
kkkkkkkkkk_Z38 分钟前
新手自学嵌入式 | 学习日记:异常与中断基础、i.MX6ULL裸机开发环境搭建、GPIO模块与点灯原理
学习
零基础12343 分钟前
Ubuntu 常用命令汇总
linux·运维·开发语言
Android系统攻城狮1 小时前
Linux Gstreamer深度解析之gst_audio_sink_get_type调用流程与实战(六十五)
linux·运维·服务器·音视频·gstreamer音视频·音视频进阶·gstreamer音视频进阶
咖啡忍者1 小时前
【SAP】程制造生产计划PP-PI(Production Planning for Process Industries)
笔记
xiaoqiMikko1 小时前
Linux 实战(一):CentOS 7、Rocky 9、Ubuntu 24.04 三台真机实测 —— 认清系统、换源、装包的版本坑
linux·centos
迷途之人不知返1 小时前
【基础IO】-1-预备知识与准备工作
linux
xiaoqiMikko1 小时前
Linux 实战(二):端口不通 —— CentOS 7、Rocky 9、Ubuntu 24.04 上防火墙和 SELinux 的实测差异
linux·centos
m4Rk_1 小时前
【论文阅读】Agent 记忆机制(94):MemGen——在推理过程中动态生成并织入潜在记忆
论文阅读·人工智能·学习·开源·github
晓德2 小时前
0、LLM大模型安全学习系列(启)
学习·安全