【操作系统】进程间的通信——信号

进程间通信-信号

信号

什么是信号/h3>

信号是给程序提供一种可以处理异步事件的方法,它利用软件中断来实现。

我们无法自定义信号,所有信号都是系统预定义的。


信号由谁产生/h3>
  1. 由shell终端根据当前发生的错误(例如:段错误、非法指令等),Ctrl+C而产生相应的信号。

比如: socket通信或管道通信,如果读端已经关闭,再执行写操作(或者进行发送数据),将导致执行写操作的进程收到SIGPIPE信号(表示管道破裂)。

该信号的默认行为——终止该进程。

  1. 在shell终端,使用kill或killall命令产生信号

示例:

  1. 在代码中调用kill函数来产生信号——详见-kill()函数 Unix/Linux

有哪些信号/h3>

信号名称 & 说明


? SIGABORT—— 进程异常终止

? SIGALRM ——超时告警

? SIGFPE —— 浮点运算异常

? SIGHUP ——连接挂断

? SIGILL——非法指令

? SIGINT ——终端中断 (Ctrl+C将产生该信号)

? SIGKILL ——*终止进程

? SIGPIPE ——向没有读进程的管道写数据

? SIGQUIT——终端退出(Ctrl+将产生该信号)

? SIGSEGV ——无效内存段访问

? SIGTERM ——终止

? SIGUSR1——*用户自定义信号1

? SIGUSR2 ——*用户自定义信号2

? ————————————–>以上信号如果不被捕获,则进程接受到后都会终止!

? SIGCHLD——子进程已停止或退出

? SIGCONT ——*让暂停的进程继续执行

? SIGSTOP ——*停止执行(即“暂停”)

? SIGTSTP——断挂起

? SIGTTIN —— 后台进程尝试读操作

? SIGTTOU——后台进程尝试写


信号的处理

  • 忽略此信号。
  • 捕捉信号,指定信号处理函数进行处理。详见信号的安装
  • 执行系统默认动作,大多数都是终止进程。

信号的捕获

信号的捕获是指,在接收到某种信号后,去执行指定的函数。

注意:

  • SIGKILL和SIGSTOP信号不能被捕获,即这两种信号的相应动作不能被改变。

信号的安装

signal

  • 其中:signal函数的返回类型与第二个参数都是函数指针类型。
  • 第二个参数中:有以下两个特殊值。
    • SIG_IGN——忽略信号
    • SIG_DFL—— 恢复默认行为

示例:


sigaction

与signal相比,sigaction更加健壮。

结构体sigaction:

补充:

  • 当sa_mask包含某个信号A时,在信号处理函数执行期间,如果发生了该信号A,则阻塞该信号A,即暂时不响应该信号,直到信号处理函数执行结束,再响应该信号A。

函数sigaction:

示例1:使用示例


示例2: 输入A主进程向子进程发送SIGUSR1信号,输出大写字符;输入a主进程向子进程发送SIGUSR2信号,输出小写字符。


示例3:使用子进程定时给父进程发送SIGALRM信号。

【操作系统】进程间的通信——信号

使用raise函数

  • 作用:给本进程自身发送某一指定信号。调用后立即发送。
  • 函数原型:int raise (int sig)
  • 示例:略。

发送多个信号

前提对应信号已绑定对应的信号处理函数。详见信号的处理。

某进程在执行某个信号对应的操作函数期间(即,该对应信号的安装函数),如果此时,该进程又多次收到同一个信号(同一种信号值的信号)。

  • 注意:
    • 如果该信号是不可靠信号(值
    • 如果该信号是可靠信号(>32),则能再响应多次(不会遗漏)。但是都必须等待该次响应函数执行完毕后,才能响应下一次。

某个进程正在执行某个信号对应的操作函数期间(该信号的安装函数),如果此时,该进程又收到一个信号(不同信号值的信号),则:

如果,该信号被包含在当前信号的signaction的sa_mask(信号搁置集)中,则不会立即处理该信号。直到当前的信号处理函数执行完毕后,才进行执行。

反之,如果该信号不在信号搁置集中,则中断当前信号处理函数,如果处于睡眠,比如sleep, 也会立即被唤醒,来执行新的这个信号处理函数,新的这个信号处理函数执行完毕后,再在返回至原来的信号处理函数继续执行。

示例:

以上详解:

  • 先收到SIGINT信号,如果此时再收到SIGUSR1,则会执行完SIGINT的信号处理函数后再进行SIGUSR1信号处理,因为SIGUSR1被加入到了响应SIGINT信号的信号搁置集中。结果如下图所示:

image-20220821131412605

信号集sigset_t

什么是信号集/h4>

例如:结构体sigaction中的参数——sigset_t sa_mask,这个sa_mask为信号搁置集。

  • 用sigset_t类型表示,实质是一个无符号长整形。

  • 用来表示包含多个信号的集合。


信号集的基本操作

  • sigemptyset——把信号集清空。
  • sigfillset——把所有已定义的信号填充到指定信号集。
  • sigdelset——从指定的信号集中删除指定的信号。
  • sigaddset——从指定的信号集中添加指定的信号。
  • sigismember——判断指定的信号是否在指定的信号集中。
    • 如果是, 返回 1。
    • 如果不是, 返回 0。
    • 信号无效, 返回-1。

进程的”信号屏蔽字”

什么是信号屏蔽字/strong>

  • 进程的”信号屏蔽字”是一个信号集,
  • 向目标进程发送某信号时,如果这个信号在目标进程的信号屏蔽字中,则目标进程将不会捕获到该信号,即不会执行该信号的信号处理函数。
  • 当该进程的信号屏蔽字不再包含该信号时,则会捕获这个早已收到的信号(执行对应的信号处理函数)。

如何修改进程的信号屏蔽字/strong>

  • 使用sigprocmask
  • 函数原型:
  • 参数列表:
  • how:
    • SIG_BLOCK——把参数set中的信号添加到信号屏蔽字中。在原来已有的基础上增加。
    • SIG_UNBLOCK——把参数set中的信号从信号屏蔽字中删除。在原来已经有的基础上删除。
    • SIG_SETMASK——把参数set中的信号设置为信号屏蔽字。原来的不生效了,新添加进的生效。
  • oldset:
    • 返回原来的信号屏蔽字,在set之前设置的,即原有的(之前设置的)信号屏蔽字。
  • 示例:

【操作系统】进程间的通信——信号

来源:半生瓜のblog

声明:本站部分文章及图片转载于互联网,内容版权归原作者所有,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2022年7月20日
下一篇 2022年7月20日

相关推荐