APUE学习---信号.docVIP

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
APUE学习---信号

?APUE学习--信号(1) 分类:?Unix环境编程2013-05-24 10:22?31人阅读?评论(0)?收藏?编辑?删除编程APUELinux信号 先说下什么是中断?由硬件产生,产生后由软件立即去执行某种操作 那么什么是信号呢?可以把信号理解为软中断,也就是说信号的产生也是由软件,并由软件立即去执行某种操作。我们这里说的信号是进程中的语义,针对的对象都是进程。信号是一种处理异步事件的方法,所谓异步,你能知道当xxx事件发生时应该执行什么样的操作,但不知道xxx事件何时会发生。 Linux系统为我们进程提供了多大64个信号,其中前32个是不可靠信号(我比较原意称其为非实时信号),后面的是可靠信号(实时信号),可以通过kill -l命令在终端中查看信号的列表,每个信号使用一个整型数表示(当然有相应的宏定义方便我们记忆)。 信号是如何产生的?可以是来自终端的按键(如ctrl+c终止进程 ctrl+\退出进程 等等)、执行过程中发生硬件异常(除数为0 段错误等)、使用kill()函数向某个进程发送信号、在终端使用kill命令向某个进程发送信号、发送某个定义的软件条件(如闹钟 子进程退出等)。 信号的产生有了,那软终端发送后,应再由软件立即去执行某种操作,那可以是什么操作呢?当信号发送后,会立即执行该信号的处理动作,每个信号的处理动作都可以不同,处理方式包括: 系统提供的默认动作(默认动作可以查看APUE这本圣经或者上度娘上很容易找到)、忽略信号什么也不做、 捕捉该信号并去执行一个自定义的函数(这个行为称为注册一个信号处理函数)。 那如何为信号设置处理动作?最简单的方法是使用signal()函数: [cpp]?view plaincopy typedef?void?(*sighandler_t)(int);?? sighandler_t??signal(int??signo,?sighandler_t?handler);?? 先从参数看起,第一个参数是一个整型的信号编号,是为哪一个信号设置处理动作;第一个参数的类型是一个指向参数为int无返回值的函数的函数指针;这个就是我们要为signo信号注册动作,三种处理方式分别对应的是SIG_DFL SIG_IGN 和 一个自定义的函数地址。这样我们就改变了一个信号的处理动作,再看返回值,类型是一个相同类型的函数指针,可以很容易推测出应该是signo信号更改之前的处理动作,也就是说可以通过返回值来保存更改之前的动作,当然如果函数执行失败,讲返回SIG_ERR。 这里需要注意的是,signal()仅仅是一个注册功能的函数,除了注册意外不做任何其他的事情,注册后,当信号产生时进程会自动执行注册的动作。整个过程是这样的:当信号到来时,程序从执行位置暂停,去执行该信号的处理动作,处理动作执行完毕后(如果动作不会使进程退出)返回暂停位置继续运行。 信号的产生条件之前说过,那如何让进程等待一个信号呢?可以使用sleep()函数,但问题是在sleep()时如果到来一个信号,sleep()函数就会被打断并返回剩余的时间,解决方法是使用循环,当sleep()的返回值为0时跳出循环 while ( (t=sleep(t)) != 0 ) 。当然这样做也无法做到让程序一直等待,替换函数式pause(),查看这个函数的帮助文档可以看到这个函数式专门用来等待一个信号的。 下面的几点需要清楚: 1.多个信号是可以注册相同的处理函数,处理函数的整型参数就是引起该函数执行的信号编号。 2.在信号处理函数执行过程中,接收到另一个信号,则仍会中断去执行另一个信号的处理动作,执行后回来继续执行。 3.在信号处理函数执行过程中,再次接受到相同的信号,并不会立刻去执行,而是信号处理函数执行结束后,再次执行处理函数。 4.在信号处理函数执行过程中,N次接受到相同的信号,在信号处理函数执行结束后情况分为两类:如果是非实时信号则只再执行一遍处理函数,如果是实时信号则执行N次处理函数。(实时信号讲会在后面详细介绍) 5.子进程会继承父进程的信号处理方式,之后父子进程中一个改变信号的处理方式不再影响另一个 6.来自终端的信号(如ctrl+c)将会发送给前台进程组中的所有进程 7.执行exec()后,信号处理动作不会被新的程序所进程,所有的信号的处理动作恢复为默认。(地址空间变了) 我们着重来看下SIGCHLD信号,进程中说到过子进程退出后需要父进程对其收尸,父进程就是通过子进程在退出时向父进程发送的SIGCHLD信号得知子进程已经退出(wait()接触阻塞)。那思考一个问题,在进程部分编写程序时,如果想收尸就需要使用wait()函数,但问题时 wait()会使进程阻塞而不能做其他事情,解决办法就是在SIGCHLD信号上做些文章,我们可以将w

文档评论(0)

xcs88858 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

版权声明书
用户编号:8130065136000003

1亿VIP精品文档

相关文档