进程间通信:信号

信号

信号是UNIX和Linux系统响应某些条件而产生的一个事件。接收到该信号的进程会相应地采取一些行动。我们用术语生成(raise)表示一个信号的产生,使用术语捕获(catch)表示接收到一个信号。

信号是由于某些错误条件而生成的,如内存段冲突、浮点处理器错误或非法指令等。它们由shell和终端处理器生成来引起中断,它们还可以作为在进程间传递消息或修改行为的一种方式,明确地由一个进程发送给另一个进程。无论何种情况,它们的编程接口都是相同的。信号可以被生成、捕获、响应或(至少对于一些信号)忽略。

信号的名称是在头文件signal.h中定义的。它们以SIG开头,见下表。
在这里插入图片描述
如果进程接收到这些信号中的一个,但事先没有安排捕获它,进程将会立刻终止。通常,系统将生成核心转储文件core,并将其放在当前目录下。该文件是进程在内存中的映像,它对程序的调试很有用处。其他信号见下表。
在这里插入图片描述
SIGCHLD信号对于管理子进程很有用。默认情况下,它是被忽略的。其余的信号会使接收它们的进程停止运行,但SIGCONT是个例外,它的作用是让进程恢复并继续执行。shell脚本通过它来控制作业,但用户程序很少会用到它。

现在,我们只需知道如果shellI和终端驱动程序是按通常情况配置的话,在键盘上敲入中断字符(通常是Ctr+C组合键) 就会向前台进程(即当前正在运行的程序)发送SIGINT信号,这将引起该程序的终止,除非它事先安排了捕获这个信号。

如果想发送一个信号给进程,而该进程并不是当前的前台进程,就需要使用kill命令。该命令需要有一个可选的信号代码或信号名称和一个接收信号的目标进程的PID(这个PID一般需要用ps命令查出来)。例如,如果要向运行在另一个终端上的PID为512的进程发送“挂断”信号,可以使用如下命令:

kill -HUB 512 #SIGHUB

信号处理

程序可以用signal库函数来处理信号,它的定义如下所示:

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

这个相当复杂的函数定义说明,signal是一个带有sig和func两个参数的函数。准备捕获或忽略的信号由参数sig给出,接收到指定的信号后将要调用的函数由参数func给出。信号处理函数必须有一个int类型的参数(即接收到的信号代码)并且返回类型为void。 signal函数本身也返回一个同类型的函数,即先前用来处理这个信号的函数,或者也可以用下表中的两个特殊值之一来代替信号处理函数。
在这里插入图片描述
另一种更好理解的定义方式:

#include <signal.h>
typedef void (*sighandler_t)(int);//先拿掉typedef,sighandler是什么类型的变量,它就代表什么类型
sighandler_t signal(int signum, sighandler_t handler);

实例演示

#include<stdio.h>
#include<stdlib.h>
#include<signal.h>

void ouch(int sig)
{
   
   printf("I got a sig : %d\n",sig);
   signal(SIGINT,SIG_DFL);
}
int main()
{
   
    signal(SIGINT,ouch);
    while(1)
    {
   
        printf<
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值