Hi,欢迎来到中国优发娱乐手机版高端品牌 - 华清远见嵌入式学院<北京总部官网>,专注嵌入式工程师培养13年!
  • 全国咨询热线:400-611-6270
  • 新浪微博
  • 微信
  • 北京
    校区
  • 上海
    校区
  • 深圳
    校区
  • 成都
    校区
  • 南京
    校区
  • 武汉
    校区
  • 西安
    校区
  • 广州
    校区
  • 沈阳
    校区
  • 济南
    校区
  • 重庆
    校区
  • 长沙
    校区
  • 研发
    中心
  • 当前位置: > 嵌入式学院 > 嵌入式学习 > 讲师博文 > Linux信号基础
    Linux信号基础
    时间:2017-05-18作者:华清远见
    一、信号使用基础知识 1.信号的发送与捕捉: 同步: 多个进程协同完成一件事情,当资源不可用时,其他的进程阻塞等待,类比流水线操作,一步一步有先后地完成一个产品。 异步: 多个进程做多项任务,同时运行,互不干扰,当需要建立联系的时候,停止运行,建立联系,处理数据,处理完成继续各自运行。异步多个进程或线程独自运行,效率较高,系统的实时性用中断实现。 信号: 内核和用户空间沟通的信使。直接进行用户空间进程和内核进程之间的交互,内核进程也可以利用它来通知用户空间进程发生了哪些系统事件。 eg: 进程结束时,内核会发送一个SIGCHLD信号以通知父进程子进程结束。内核向用户发送信号时,用户进程可以进程阻塞。就像项目不能因为一个无名信号出错而结束进程。 ________________________________________ 2.信号的周期: 红色中的的内容都是内核操作,与用户程序无关,用户程序就是信号处理。 信号由内核产生,要由用户空间进行注册和注销。信号处理是定义的处理方式,相当于内核到用户的一次切换。 用户的处理方式有三种: 1)忽略 不理踩,有两个信号不可以忽略(KILL和STOP信号); 2)捕捉 捕捉信号后,自定义处理方式,(用signal()进行注册); 3)默认 系统默认处理方式。 ________________________________________ 3.信号处理流程: PS: 实际执行信号的处理动作称为信号投递(Delivery),信号从发生到投递之间的状态,称为信号未决(Pending)。 进程可以选择阻塞(Block)某个信号。被阻塞的信号产生后将保持在未决状态,直到进程解除对此信号的阻塞,才执行投递的动作。 每个信号都有两个标志位分别表示阻塞和未决,还有一个函数指针表示处理动作。 信号产生时,内核在进程控制块中设置该信号的未决标志(表示某信号是否发生过),直到信号投递完毕才清除该标志。在上图的例子中, 1. SIGHUP信号未阻塞也未产生过,当它递达时执行默认处理动作。 2. SIGINT信号产生过,但正在被阻塞,所以暂时不能投递。虽然它的处理动作是忽略,但在没有解除阻塞之前不能忽略这个信号,因为进程仍有机会改变处理动作之后再解除阻塞。 3. SIGQUIT信号未产生过,一旦产生SIGQUIT信号将被阻塞,它的处理动作是用户自定义函数sighandler。 未决和阻塞标志可以用相同的数据类型sigset_t来存储,sigset_t称为信号集,这个类型可以表示每个信号的“有效”或“无效”状态,在阻塞信号集中“有效”和“无效”的含义是该信号是否被阻塞,而在未决信号集中“有效”和“无效”的含义是该信号是否处于未决状态。 ________________________________________ 4.信号应用的场合: ________________________________________ 5.常用的几种信号与默认方式:  SIGALRM定时信号,定时N秒,时间到,发送一个闹钟信号,终止进程。   对信号的处理方式解释: 1)忽略此信号 除了两种信号(SIGKILL和SIGSTOP)不能被忽略外,其它的的信号都可被忽略,这两个信号不能被忽略的原因是:它们提供一种终极的终止或停止进程的可靠方法,这是一种终极裁判权,如果这两个信号都被忽略了的话,某个进程跑飞后就没有办法终止或停止这个进程。 另外忽略某些硬件产生的信号被认为是不可取的,如我们如果忽略非法存储访问或除以0等硬件产生的信号的话,进程状态未定义的(无法确定的状态)。 2)捕获信号 如果某个进程被通知某个信号发生了,但是想要捕获这个信号的话,该进程就必须向内核注册一个捕获函数,当相应的信号发生时,捕获函数就会被调用并执行希望对这个事件的处理。 3)执行系统的默认操作 其实我们内核为每个信号在发生时都规定了一个默认的操作,如果我们不捕获也不忽略的话,当这个信号发生时,进程会按照默认方式去处理这些发生的信号,当然对于绝大多数信号而言,其默认的处理方式都是终止接收到该信号的进程或者忽略此信号。   /**************************************************************************拓展: 查看信号的方法:  kill  -l  或man 7 signal     通常有62以上,kill -l 列出的前面32个是非实时的,signal函数只能使用前( 1 -- 31),后面为拓展信号,signal不能用,中间缺少的没有编号。前面(1 -- 31)是非实时的,信号不支持排队,可能造成信号丢失。有预定义的含义和处理方式函数。后面的实时信号支持排队   各种信号说明: http://www.2cto.com/os/201608/537204.html (感谢博主详细列出了各种信号) ***************************************************************************/ 我们常用的有: INT, QUIT, KILL, USR1, USR2  ALRM   STOP TERM . USR1,和USR2在硬件中没有任何价值,在应用程序中,可以使用usr1和usr2进行自定义通信。 TTOU/TTIN网络开发中常用的信号,IO信号在网路常用。 ________________________________________ 二、相关系统调用: 1.kill()和raise()    pid  =  -1,向所有进程发送信号(除了init进程)。 sig = 0;表示只检查错误信息,不发送信号。没有0号编号信号。 kill示例: raise示例: 当前进程进入stop态,发送CONT信号继续运行。如果发送的是USR1信号,默认进程退出。 ________________________________________ 2.alarm()和pause() 0.alarm是指定一定时间后发送信号。 1.要注意的是,一个进程只能有一个闹钟时间。如果在调用alarm时已设置过闹钟时间,则之前的闹钟时间被新值所代替。 2.alarm函数只设置时钟,设置完成后,程序向下继续运行。(补充说明alarm函数只是设置定时闹钟,并不阻塞); 3.等待信号来临可以利用while检测等待或利用pause函数将进程挂起。 pause()接收任意信号就会结束挂起。 示例代码: myalarm.c mypause.c 利用alarm和pause实现sleep功能: 补充: alarm()和sleep()函数不同,alarm信号并不会阻塞,相当于订了闹钟后,系统在后台计时,到了指定时间就会发送ALRM信号;sleep()函数会使进程进入睡眠态,进程暂停执行,直到时间结束。

    发表评论
    全国咨询电话:400-611-6270,双休日及节假日请致电值班手机:15010390966 在线咨询: 曹老师QQ(3337544669), 徐老师QQ(1462495461), 刘老师 QQ(3108687497) 企业培训洽谈专线:010-82600901,院校合作洽谈专线:010-82600350,在线咨询:QQ(248856300) Copyright 2004-2017 华清远见教育集团 版权所有 ,沪ICP备10038863号,京公海网安备110108001117号

    优发娱乐手机版

    百度360搜索搜狗搜索

    优发娱乐手机版

    百度360搜索搜狗搜索