信号(一)

2016-02-15

信号

信号概念

每个信号都有一个名字,这些名字都以三个字符SIG开头。eg SIGABRT SIGALRM
在头文件<signal.h>中,这些信号都被定义为正整数。很多条件会产生一个信号

  • 当用户按某些终端键时,产生信号。在终端上按DELETE键通常产生中断信号(SIGINT)这是停止一个已经失去控制程序的方法。
  • 硬件异常产生信号:除数为0、无效的存储访问等等。这些条件通常由硬件检测到,并将其通知内核。然后内核为该条件发生时正在运行的进程产生适当的信号。
  • 进程调用kill(2)函数可将信号发送给另一个进程或进程组。接收信号进程和发送信号进程的所有者必须相同,或发送信号进程的所有者必须是超级用户。
  • 当检测到某种软件条件已经发生时,并将其通知有关进程时也产生信号。这里并不指硬件产生条件,而是软件条件,如SIGURG(在网络连接上传来非规定波特率的数据)、SIGPIPE(在管道的读进程已终止后一个进程写此管道),以及SIGALRM(进程所这只的闹钟时间已经超时)

信号是一步时间的经典实例。产生信号的事件对进程而言是随机出现的。进程不能只是测试一个变量来判别是否发生了一个信号,而是必须告诉内核“在此信号发生时,请执行下列操作”
可以要求系统在某个信号出现时按照下列三种方式中的一种进行操作

  • 忽略此信号。大多数信号都可使用这种方式进行处理。但有两种信号绝不能被忽略。SIGKILL和SIGSTOP这两种信号不能被忽略的原因是他们向超级用户提供一种使进程停止或者终止的可靠方法。另外如果忽略某些由硬件异常产生的信号,则继承的行为是未定义的。

  • 捕捉信号。为了做到这一点要通知内核在某种信号发生时,调用一个用户函数。在用户函数中,可执行用户希望对这种时间进程的处理。

  • 执行系统默认动作。对大多数信号的系统默认动作是终止该进程。
    在系统默认动作列 终止w/core表示在进程当前工作目录的core文件中复制了该进程的存储图像。大多数unix调试程序都是用core文件检查进程终止时的状态。在下列条件下不产生core文件 进程是设置用户id而且当前用户并非程序文件所有者,进程是设置组id而当前用户并非该程序文件的组所有者,或者用户没有写当前目录的权限,或者文件太大。core文件的许可权通常是用户读写组读和其他读

  • SIGABRT 调用abort函数时产生此信号。进程异常终止。

  • SIGALRM 超过用alarm函数设置的时间时产生此信号。若由settimer函数设置的时间间隔已经过时,那么也产生此信号。

  • SIGBUS 只是一个实现定义的硬件故障。

  • SIGCHLD 在一个进程终止或者停止时,SIGCHLD信号被送给其父进程。按系统默认,将忽略此信号。如果父进程希望了解其子进程的这种状态,则应捕捉此信号。信号捕捉函数中通常要用wait函数以取得子进程id和终止状态

  • SIGCONT 此作业控制信号送给需要继续运行的处于停止状态的进程。如果接收到此信号的进程处于停止状态,则系统默认动作是使该进程继续运行,否则默认动作是忽略。

  • SIGEMT 指示一个实现定义的硬件故障。

  • SIGFPE 此信号表示一个算术运算异常。

  • SIGHUP 如果终端界面检测到一个连接断开,则此信号传送给该终端相关的控制进程。

  • SIGILL 此信号指示进程已执行一条非法硬件指令。

  • SIGINFO 当用户按状态键(ctrl+T)终端驱动程序产生此信号并送至前台进程组中的每一个进程。此信号通常造成在终端上显示前台进程组中各进程的状态信息。

  • SIGINT 当用户按中断键终端驱动程序产生此信号并送至前台进程组的每一个进程。

  • SIGIO 此信号指示一个异步io事件

  • SIGIOT 表示一个实现定义的硬件故障

  • SIGKILL 杀死进程

  • SIGPIPE 如果在读进程已终止时写管道,则产生此信号。

  • SIGPOLL 当在一个可轮询的设备上发生一特定事件时产生此信号。

  • SIGPROF 当setitimer函数设置的梗概统计时间间隔已超过时产生此信号

  • SIGPWR 它主要用于具有不间断电源的系统上。如果电源失效,则ups起作用,而且通常软件会接到通知。

  • SIGQUIT 当用户在终端上按退出键时产生此信号,并送至前台进程组所有进程。此信号不仅终止前台进程组,同时产生一个core文件

  • SIGSEGV 进程进行了一次无效的存储访问

  • SIGSTOP 这是一个作业控制信号,它停止一个进程,它类似交互停止信号SIGTSTP但其不能被捕捉或忽略。

  • SIGSYS 指示一个无效的系统调用。

  • SIGTERM 这是kill命令发送的系统默认终止信号

  • SIGTRAP 指示一个实现定义的硬件故障

  • SIGTSTP 交互停止信号,当用户在终端上按挂起键(一般Ctrl+Z)时终端驱动产生此信号。

  • SIGTTIN 当一个后台进程组试图读其控制终端时,终端驱动程序产生此信号。

  • SIGTTOU 当一个后台进程组进程试图写其控制终端信号时产生此信号

  • SIGURG 此信号通知进程已经发生一个紧急情况。在网络连接上,接到非规定波特率的数据时此信号可选择的产生。

  • SIGUSR1 这是一个用户定义的信号,可用于应用程序

  • SIGUSR2 用户自定义信号

  • SIGVTALARM 当一个由setitimer函数设置的虚拟间隔时间已经超过时产生此信号。

  • SIGWINCH 内核保持与每个终端或者伪终端相关联的窗口大小。一个进程可以用ioctl函数得到或者设置窗口大小。如果一个进程用ioctl设置了窗口大小则发送此信号

  • SIGXCPU 如果进程超过了其软cpu时间限制则产生此信号

  • SIGXFSZ 如果进程超过了其软文件长度限制,则产生此信号。

signal函数

#include<signal.h>
void (*signal (int signo, void(*func)(int)))(int);

signo参数时信号名,func的值是:常数SIG_IGN表示忽略此信号,SIG_DFL表示默认动作,当指定函数地址时我们称此为捕捉此信号。我们称此函数是信号处理程序或者信号捕捉函数

程序启动

当执行一个程序时,所有信号的状态都是系统默认或者忽略。通常都是系统默认,除非调用exec的进程忽略该信号。比较特殊的是exec函数将原先设置为要捕捉的信号都设置为默认动作,其他信号的状态则不变(一个进程原先要捕捉的信号,当其执行一个新的程序后紫檀不能再捕捉了,因为信号捕捉函数的地址很可能在所执行的新程序文件中已无意义)

进程创建

当一个进程调用fork时其子进程继承父进程的信号处理方式,因为子进程在开始时复制了父进程存储图像,所以信号捕捉函数的额地址在子进程中是有意义的。

不可靠信号

早期的unix版本中信号发生后进程不一定会收到。那时进程对信号的控制能力也很低,它能捕捉信号或者忽略它,但有些很需要的功能并不具备。例如有时用户希望通知内核阻塞一信号不忽略该信号,在其发生时记住它,然后再进程做好了准备时再通知他,这种阻塞信号的能力当时并不具备。
早期版本中的一个问题是在进程每次处理信号时随即将信号动作复置为默认值。这些早期版本的另一个问题是在进程不希望某种信号发生时,它不能关闭该信号。进程能做的就是忽略该信号。

中断的系统调用

早期的unix系统的一个特性是:如果在进程执行一个低速系统调用而阻塞期间捕捉到一个信号,则该系统调用就被中断不再继续执行。该系统调用返回出错,其errno设置为EINTR。这样处理的理由是因为一个信号发生了,进程捕获了它,这意味着已经发生了某种事情,所以是个好机会应当缓行阻塞的系统调用。
为了支持这种特性,将系统调用分成两类:低速系统调用和其他系统调用。低速系统调用是可能会使进程永远阻塞的一类系统调用,其包括:

  • 在读某些类型的文件时,如果数据并不存在则可能会使调用者永远阻塞。
  • 在写这些类型的文件时,如果不能立即接受这些数据,则也可能会使调用者永远阻塞
  • 打开文件,在某种条件发生之前也可能会使调用者阻塞(如:打开终端设备,它要等待直到所连接的调制解调器回应)
  • pause和wait
  • 某种ioctl操作
  • 某些进程间通信函数

在这些低速系统调用中一个值得注意的例外是与磁盘io有关的系统调用。虽然读写磁盘文件有可能暂时阻塞调用者,但除非发生硬件错误,io操作总会很快返回。
可以用中断系统调用这种方法来处理的一种情况是一个进程启动了读终端的操作,而使用该终端设备的用户却离开终端很长时间。这种情况下进程可能处于阻塞状态几小时甚至数天,,除非系统停机。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,390评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,821评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,632评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,170评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,033评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,098评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,511评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,204评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,479评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,572评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,341评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,893评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,171评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,486评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,676评论 2 335

推荐阅读更多精彩内容

  • Linux 中的信号 在类 Unix 操作系统中,信号被用于进程间通信。信号是一个发送到某个进程或同一进程中的特定...
    赵者也阅读 441评论 0 0
  • Linux 进程管理与程序开发 进程是Linux事务管理的基本单元,所有的进程均拥有自己独立的处理环境和系统资源,...
    JamesPeng阅读 2,442评论 1 14
  • 又来到了一个老生常谈的问题,应用层软件开发的程序员要不要了解和深入学习操作系统呢? 今天就这个问题开始,来谈谈操...
    tangsl阅读 4,077评论 0 23
  • 地点:北回归线以北 时间:冬至 备注:白昼最短,黑夜最长的一天,过了今天,太阳会从那遥远的南半球缓缓而来,一点点将...
    薇雨青芜阅读 862评论 12 28
  • 文/稻草人 自古佛前香烟少,红尘痴情男女多。 愿做佛前香一炷,不做红尘痴心人。 2...
    疯狂稻草人阅读 288评论 13 8