信号可靠性剖析

问题

基于信号发送的进程间通信方式可靠吗???

信号查看(kill -l)

信号可靠性剖析_第1张图片

信号的分类

不可靠信号 (传统信号)

  • 信号值在 [1, 31] 之间的所有信号

可靠信号 (实时信号)

  • 信号值在 [SIGRTMIN,SIGRTMAX],即:[34,64]
  • SIGRTMIN => 34
  • SIGRTMAX => 64

信号小知识

信号 32 与信号 33 (SIGCANCEL & SIGSETXID) 被NPTL 线程库征用

NPTL => Native Posix  Threading Library

  • 即:POSIX 线程标准库,Linux 可以使用这个库进行多线程编程

对于 Linux 内核,信号 32 是最小的可靠信号

SIGRTMIN 在 signal.h 中定义,不同平台的 linux 可能不同 (arm linux)

不可靠信号 vs 可靠信号

不可靠信号

  • 内核不保证信号可以递送到目标进程 (内核对信号状态进行标记)
  • 如果信号处于未决状态,并且相同信号被发送,内核丢弃后续相同信号

可靠信号

  • 内核维护信号队列,未决信号位于队列中,因此信号不会被丢弃
  • 严格意义上,信号队列有上限,因此不可以无限制保存可靠信号

一些注意事项。。。

不可靠信号的默认处理行为可能不同 (忽略,结束)

可靠信号的默认处理行为都是结束进程

信号的可靠性由信号数值决定,与发送方式无关

信号队列的上限可通过命令设置

查询信号队列上限:ulimit -i

设置信号队列上限:ulimit -i 1000

信号可靠性试验设计

目标:验证信号可靠性 (不可靠信号 or 可靠信号)

方案:对目标进程 "疯狂" 发送 N 次信号,验证信号处理函数调用次数

预备函数:

  • int sigaddset(sigset* set, int signum);
  • int sigdelset(sigset_t* set, int signum);
  • int sigfillset(sigset_t* set);
  • int sigfillset(sigset* set);
  • int sigemptyset(sigset* set);
  • int sigprocmask(int how, const sigset* set, sigset* oldset);

信号可靠性剖析_第2张图片

基于信号的进程间通信实验

A 进程将 TLV 类型的数据通过可靠信号传递给 B 进程

  • TLV => (type, length, value)
  • 由于可靠信号的限制,每次传输4字节数据

B 进程首先接收 4 字节数据 (type 或 type + length)

  • 根据接收到 length 信息,多次接收后续的字节数据
  • 每次只能接收 4 字节数据,设计层面需要进行状态处理

状态设计

信号可靠性剖析_第3张图片

数据发送进程关键实现

信号可靠性剖析_第4张图片

数据接收进程关键实现

信号可靠性剖析_第5张图片

你可能感兴趣的:(Linux系统编程,linux)