一、信号(Signal)机制

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

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

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

2.1、信号表

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

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

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

取值名称取值名称取值名称
34SIGRTMIN35SIGRTMIN+136SIGRTMIN+2
37SIGRTMIN+338SIGRTMIN+439SIGRTMIN+5
40SIGRTMIN+641SIGRTMIN+742SIGRTMIN+8
43SIGRTMIN+944SIGRTMIN+1045SIGRTMIN+11
46SIGRTMIN+1247SIGRTMIN+1348SIGRTMIN+14
49SIGRTMIN+1550SIGRTMAX-1451SIGRTMAX-13
52SIGRTMAX-1253SIGRTMAX-1154SIGRTMAX-10
55SIGRTMAX-956SIGRTMAX-857SIGRTMAX-7
58SIGRTMAX-659SIGRTMAX-560SIGRTMAX-4
61SIGRTMAX-362SIGRTMAX-263SIGRTMAX-1
64SIGRTMAX

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实现,如果信号量的值为非正数,表明有任务等待当前信号量,因此它也唤醒所有等待该信号量的任务。