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编译,不需要额外库。

相关推荐
代码山河2 小时前
Python就业方向全解析:后端、爬虫、数据分析、AI你选哪个?
python·学习·架构·教程·面向对象·项目
HideF2 小时前
Linux
linux·服务器·网络
sbjdhjd2 小时前
网工进阶笔记:H3CSE 园区网全栈技术与协议汇总
网络·笔记·云计算·ssh·网络工程·vlan·aaa
释厄6232 小时前
AI学习层更新与跨体转移律——人类社会同构·不缺理解缺 U
人工智能·学习
Ruiery4 小时前
Linux 6.6内核内存管理深度解析(十三):slab/slub 分配器
linux·运维·服务器
海绵宝宝的月光宝盒5 小时前
14-AutoCAD-阵列命令应用与案例实战(AR)
经验分享·笔记·自动化·课程设计·制造·学习方法·cad
丰锋ff6 小时前
压缩命令笔记
linux
小嘉丶学长6 小时前
Day14 · 字典与集合
java·开发语言·网络·python·学习·1024程序员节
白山编程大哥6 小时前
接口幂等性是什么?如何设计?
笔记
ACP广源盛139246256737 小时前
6 盘位存储扩展方案选型笔记:YLB3116 @ACP评估记录
笔记·硬件架构·硬件工程·国产芯片