Linux的信号与信号量机制

一、信号(Signal)机制

Signal,又简称为信号(软中断信号)用来通知进程发生了异步事件,是一种处理异步事件的方式。一个进程不必通过任何操作来等待信号的到达,事实上,进程也不知道信号到底什么时候到达。进程之间可以互相通过系统调用kill发送软中断信号。内核也可以因为内部事件而给进程发送信号,通知进程发生了某个事件。信号机制除了基本通知功能外,还可以传递附加信息。

按照不同的分类角度(可靠性方面,与时间的关系上)可以对信号进行区分:

  • 可靠信号(实时信号):支持排队, 信号不会丢失,发多少次进程就可会收到多少次,信号值取值区间为34~64
  • 不可靠信号(非实时信号):不支持排队,信号可能会丢失,比如发送多次相同的信号,进程只能收到一次,信号值取值区间为1~31

2.1、信号表

2.1.1、不可靠信号(非实时信号)表

取值 名称 解释 取值 名称 解释
1 SIGHUP 挂起 2 SIGINT 中断
3 SIGQUIT 退出 4 SIGILL 非法指令
5 SIGTRAP 断点或陷阱指令 6 SIGABRT abort发出的信号
7 SIGBUS 非法内存访问 8 SIGFPE 浮点异常
9 SIGKILL kill信号 10 SIGUSR1 用户信号1
11 SIGSEGV 无效内存访问 12 SIGUSR2 用户信号2
13 SIGPIPE 管道破损,没有读端的管道写数据 14 SIGALRM alarm发出的信号
15 SIGTERM 终止信号 16 SIGSTKFLT 栈溢出
17 SIGCHLD 子进程退出 18 SIGCONT 进程继续
19 SIGSTOP 进程停止 20 SIGTSTP 进程停止
21 SIGTTIN 进程停止,后台进程从终端读数据时 22 SIGTTOU 进程停止,后台进程向终端写数据时
23 SIGURG I/O有紧急数据到达当前进程 24 SIGXCPU 进程的CPU时间片到期
25 SIGXFSZ 文件大小的超出上限 26 SIGVTALRM 虚拟时钟超时
27 SIGPROF profile时钟超时 28 SIGWINCH 窗口大小改变
29 SIGIO I/O相关 30 SIGPWR 关机
31 SIGSYS 系统调用异常

2.1.2、可靠信号(实时信号)表

取值 名称 取值 名称 取值 名称
34 SIGRTMIN 35 SIGRTMIN+1 36 SIGRTMIN+2
37 SIGRTMIN+3 38 SIGRTMIN+4 39 SIGRTMIN+5
40 SIGRTMIN+6 41 SIGRTMIN+7 42 SIGRTMIN+8
43 SIGRTMIN+9 44 SIGRTMIN+10 45 SIGRTMIN+11
46 SIGRTMIN+12 47 SIGRTMIN+13 48 SIGRTMIN+14
49 SIGRTMIN+15 50 SIGRTMAX-14 51 SIGRTMAX-13
52 SIGRTMAX-12 53 SIGRTMAX-11 54 SIGRTMAX-10
55 SIGRTMAX-9 56 SIGRTMAX-8 57 SIGRTMAX-7
58 SIGRTMAX-6 59 SIGRTMAX-5 60 SIGRTMAX-4
61 SIGRTMAX-3 62 SIGRTMAX-2 63 SIGRTMAX-1
64 SIGRTMAX

2.2、信号触发

  • 硬件方式:
    • 终端输入:例如, Ctrl + C(SIGINT)Ctrl + \(SIGQUIT)Ctrl + Z(SIGTSTP)
    • 硬件检测异常:由硬件检测到并通知内核并由内核向当前进程发送适当的信号。例如除 0 导致 CPU 产生异常,内核将该异常解释为 SIGFPE 信号发送给进程,访问非法内存地址导致 MMU 产生异常,内核将该异常解释为 SIGSEGV 信号发送给进程;
  • 软件方式:
    • 使用如下指令给进程发送信号:kill()raise()sigqueue()alarm()abort()等;

2.3、信号处理

  • 默认:默认的处理方式;
  • 自定义:使用自定义的信号捕获函数捕获信号后进行处理;
  • 忽略:对指定信号不做处理;

二、信号量(Semaphore)机制

信号量在创建时需要设置一个初始值,表示同时可以有几个任务可以访问该信号量保护的共享资源,初始值为1就变成互斥锁(Mutex),即同时只能有一个任务可以访问信号量保护的共享资源,是进程间通信处理同步互斥的机制

一个任务要想访问共享资源,首先必须得到信号量,获取信号量的操作将把信号量的值减1,若当前信号量的值为负数,表明无法获得信号量,该任务必须挂起在该信号量的等待队列等待该信号量可用;若当前信号量的值为非负数,表示可以获得信号量,因而可以立刻访问被该信号量保护的共享资源。

当任务访问完被信号量保护的共享资源后,必须释放信号量,释放信号量通过把信号量的值加1实现,如果信号量的值为非正数,表明有任务等待当前信号量,因此它也唤醒所有等待该信号量的任务。

Author: bugwz
Link: https://bugwz.com/2017/07/12/singnal-semaphore/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.