-
信号是软件中断。它即可以作为进程间通信的一种机制,更重要的是,信号总是中断一个进程的正常运行,它更多地被用于处理一些非正常情况。
-
信号是异步的,进程并不知道信号什么时候到达。
-
进程既可以处理信号,也可以发送信号给特定进程。
-
每个信号都有一个名字,这些名字都以SIG开头。例如:SIGABRT是进程异常终止信号。
查看信号的命令:kill -l
信号的种类
- 不可靠的信号:Linux信号机制基本上是从Unix系统中继承过来的。早期Unix系统中的信号机制比较简单和原始,后来在实践中暴露出一些问题,因此,把那些建立在早期机制上的信号叫做“不可靠信号”,信号值小于SIGRTMIN的叫不可靠信号。(前31个信号)
每次信号处理后,该信号对应的处理函数会恢复到默认值。
信号可能丢失。 - 可靠信号:信号值位于SIGRTMIN和SIGRTMAX之间的信号都是可靠信号,可靠信号克服了信号可能丢失的问题 。
- 非实时信号与实时信号:Linux目前定义了64种信号(将来可能会扩展),前面32种为非实时信号,后32种为实时信号。非实时信号都不支持排队,都是不可靠信号,实时信号都支持排队,都是可靠信号。
core 文件
- core文件的简单介绍
在一个程序崩溃时,它一般会在指定目录下生成一个core文件。core文件仅仅是一个内存映象(同时加上调试信息),主要是用来调试的。 - 开启或关闭core文件的生成
用以下命令来阻止系统生成core文件:
ulimit -c 0
下面的命令可以检查生成core文件的选项是否打开:
ulimit -a
该命令将显示所有的用户定制,其中选项-a代表“all”。
ulimit -c unlimited来让特定的用户可以产生core文件
ulimit -c 0 则也是禁止产生core文件,
而ulimit -c 1024则限制产生的core文件的大小不能超过1024kb - 使用core文件
在core文件所在目录下键入:gdb -c core,它会启动GNU的调试器,来调试core文件,并且会显示生成此core文件的程序名,中止此程序的信号等等,如果你已经知道是由什么程序生成此core文件的,比如MyServer崩溃了生成core.12345,那么用此指令调试:gdb -c core.12345 MyServer
信号的相关概念
- 信号的产生:
当引发信号的事件发生时,为进程产生一个信号(或向一个进程发送一个信号)。信号产生时,内核会在进程表中设置一位标识。 - 信号的递送(delivery):
当进程对信号采取动作(执行信号处理函数或忽略)时称为递送。
信号产生和递送之间的时间间隔内称信号是未决的(pending)。 - 信号递送阻塞(block):
进程可指定对某个信号采用递送阻塞,如果此时信号的处理是系统默认动作或者捕捉该信号,则该信号就会处于未决的状态,直到进程解除对该信号的递送阻塞或者处理方式改为忽略。 - 如果信号的处理方式是忽略该信号,那么该信号永远不会处于递送或者递送未决状态
信号的使用
进程可以从三个方面使用信号:
- 指定当收到信号时进程的处理函数(信号处理)。
- 阻塞一个信号(也就是推迟它的递送),比如处于一段临界代码,执行完临界代码后在启用这个信号。
- 向另外一个进程发送信号(进程间通讯)。
初始屏蔽字都为0,当有信号产生,即信号产生标记为1时,如果对应的屏蔽字为0,则信号递送,然后信号产生标记置为0,屏蔽字置为1,当信号处理完毕之后,屏蔽字再次回归0;如果对应的屏蔽字为1,则信号阻塞。
信号的处理
进程在接收到一个信号时,通常可以进行三种处理:
- 忽略此信号:大多数信号都可使用这种方式进行处理,但有两种信号却不能被忽略。它们是:SIGKILL和SIGSTOP。这两种信号不能被忽略的原因时:它们向超级用户提供一种进程终止或或停止的可靠方法;
- 捕捉信号:为了做到这一点要通知内核在某种信号发生时,调用一个用户函数。在用户函数中,可执行用户希望对这种事件进行的处理。
- 执行系统默认动作:对大多数信号的系统默认动作是终止该进程。
1. signal 信号注册函数:用来通知内核如何处理某个特定信号(忽略、捕捉、默认处理)