进程中的信号

                                                    进程中的信号

                                                                         作者:下家山

一:进程中的信号

1.1信号的定义:

信号是unix和linux系统响应某种条件而产生的一个事件。

接收到该信号的进程会相应的采取一些行动。

1.1.1 实例解析

当我们在ubuntu上ping www.baidu.com的时候,ping程序一直在运行,直到我们按下ctrl+C,ping程序才会停止。

首先我们linux系统中有个程序在运行【进程,这个进程能够捕获到ctrl+c按键】,当我们按下ctrl+c时,相当于发出了一个信号,该进程接收到这个信号后,采取一些行动。【这个行动,就是终止前台进程】

 

1.1.2 信号的一些属性

我们用术语raise(生成)表示一个信号的产生。

使用术语catch(捕获)表示接收到一个信号。

信号,是由某些错误条件而生成的,如内存段冲突,浮点处理器错误或非法指令等。他们由shell和终端处理器生成来引起中断,他们还可以作为在进程间传递消息或修改行为的一种方式,明确的由一个进程发给另一个进程。

信号可以被生成,捕获,响应或忽略。

 

 

1.1.3 系统中有哪些信号

                       Linux系统中的信号命名

信号名称

说明

SIGABORT

进程异常终止

SIGALRM

超时警告

SIGFPE

浮点运算异常

SIGHUP

链接挂断

SIGILL

非法指令

SIGINT

终端中断

SIGKILL

终止进程(此信号不能被捕获或忽略)

SIGPIPE

如果你试图向一个管道或套接口写入,当读取方关闭连接,你将得到一个SIGPIPE的信号,它会使进程终止除非指定处理方法。

SIGQUIT

终端退出

SIGSEGV

无效内存段访问

SIGTRM

终止

SIGUSR1

用户定义信号1

SIGUSR2

用户定义信号2

 

 

 

 

 

 

如果进程接收到这些信号中的一个,但事先没有安排捕获它,进程将会立刻终止。【对这句话的理解,看下面的例子就明白了,如果你在shell提示符下运行了一个前台进程,而且你的代码里面没有捕获ctrl+c的代码,那么,当用户按下ctrl+c时,你所运行的这个进程将会退出】

通常,系统将生成核心转储文件core,并将其放在当前目录下。该文件是进程在内存中的映像,它对程序的调试很有用处。

其他信号如下:

                       Linux系统中的信号命名

信号名称

说明

SIGCHLD

子进程已经停止或退出

SIGCONT

继续执行暂停进程

SIGSTOP

停止执行(此信号不能被捕获或忽略)

SIGTSTP

终端挂起

SIGTTIN

后台进程尝试读操作

SIGTTOU

后台进程尝试写操作

SIGCHLD信号对于管理子进程很有用。默认情况下,它是被忽略的。其他信号会使接收它的进程停止运行,但SIGCONT是一个例外,它的作用是让进程恢复并继续执行。Shell脚本通过它来控制作业,但用户程序很少会用到它。

1.1.4 杀死前台进程

如果我们对shell和终端驱动程序是按照通常情况配置的话,当我们在键盘按下终端中断字符(Ctrl+C的组合键)就会向前台进程(即当前运行的程序)发生SIGINT信号,这将引起该程序终止,除非它事先安排了捕获这个信号。

1.1.5 杀死后台进程

如果想发生一个信号给进程,而该进程并不是当前的前台进程,就需要使用kill命令。该命令需要有一个可选的信号代码或信号名称和一个接收信号的目标进程的PID(这个PID一般需要用ps命令查出来)。

 

【实例解析】

 当我们在后台运行ctrl_c进程$./ctrl_c &,实际上系统会报出它的进程ID是6303,不需要我们通过ps命令查看。(前台运行的进程,才需要ps查看ID)

 然后,当我们输入kill -HUP 6003回车,进程ctrl_c进程终止,但是shell提示符并没有出来,需要我们在运行ctrl_c进程的终端上敲回车键才可以显示shell提示符。

按了回车键后,终端跳出:

 

Kill当然也可以杀死前台进程

 

 

 

当我们在另一个终端,通过ps查到ctrl_c的进程ID是6002,然后通过kill杀掉它的时候,ctrl_c进程会被终止,跳出Terminated字符。

1.1.6 killall通杀令

Kill命令有一个有用的变体叫killall,它可以给运行着某一命令的所有进程发送信号。并不是所有的unix系统都支持它,但是linux系统一般都有该命令。如果不知道某个进程的ID,或者想给执行相同命令的许多不同的进程发送信号,这条命令就很有用了。

1.2 如何用函数来处理信号

Ctrl+c,kill,killall这类命令需要在终端下操作,程序设计很不方便,灵活,如何使用函数来实现呢!

1.2.1 信号处理函数signal

#include <signal.h>

Void (*signal (int sig, void (*func)(int))) (int);

这个相当复杂的函数定义说明:

1,signal是一个带有sig和func两个参数的函数。

2,sig参数表示要捕获或忽略的信号;

3,func是一个函数指针,接收到指定的信号后将要调用的函数由参数func给出;

**************下面讲解了实例后回头看比较好**********************

4,信号处理函数必须有一个int类型的参数(即接收到的信号代码)

 

并且返回类型为void。

Signal函数本身也返回一个同类型的函数,即先前用来处理这个信号的函数,

,或者也可以用下面的两个特殊值之一来代替信号处理函数。

                       信号处理函数中的特殊值

名称

说明

SIG_IGN

忽略信号

SIG_DFL

恢复默认行为

 

1.2.2  signal实例

我们通过一个实例可以很清楚的理解信号的处理方法。

我们将写一个程序ctrl_c_signal.c,它将响应用户敲入的Ctrl+C组合键,在屏幕上打印一条信息而不是终止程序的运行。当用户第二次按下Ctrl+C时,程序真正的终止退出。

1.2.3  signal实例解析

Main函数的作用是,截获按下Ctrl+C组合键时产生的SIGINT信号。没有信号出现时,它会在一个无限循环中每隔一秒打印一条信息。

第一次按下Ctrl+C会让程序作出响应,然后程序继续执行。再次按下Ctrl+C时,程序将结束运行,因为SIGINT的处理方式已经恢复默认行为——终止程序的执行。

在此例中,我们可以看到,信号处理函数

void catch(int sig)

使用了一个单独的整数参数sig,它就是引起该函数被调用的信号代码。如果需要在同一个函数中处理多个信号,这个参数就很有用。

1.2.4 signal函数的弊端

如果想保留信号处理函数,让它继续响应用户的Ctrl+C组合键,我们就需要再次调用signal函数来重新建立它。这会使信号在一段时间内无法得到处理,这段时间从调用中断函数开始,到信号处理函数的重建为止。如果在这段时间内程序接收到第二个信号,它就会违背我们的意思。

1.3 kill传递信号

1.3.1 kill实例

1.3.2 kill实例解析

 

Kill.c第一个函数ding是模拟一个闹钟。

在main函数中,我们告诉子进程在等待5秒后发送一个SIGALRM信号给它的父进程。

当fork函数返回值为0时,说明是子进程代码在运行;

当fork函数返回值大于0时,说明是父进程代码在运行;

这里为什么要sleep(5)呢,是因为子进程要发送一个SIGALRM信号父进程,所以一定要等到父进程捕获函数【(void )signal(SIGALRM,ding)】成功运行起来,所以这个5秒是估算的。

子进程通过kill函数向父进程发送SIGALRM信号;

父进程通过(void )signal(SIGALRM,ding)捕获SIGALRM信号,如果捕获到了,启动信号处理函数ding。

父进程启动信号处理函数后,调用了一个pause函数,该函数将等待有一个信号出现【这里就是SIGALRM】,并且这个信号处理完毕【也就是ding函数返回】

1.3.3 kill函数和kill命令

我们杀死一个进程通常是kill 进程号,实际上kill命令就是通过Kill函数来实现的,只不过当输入kill 进程号的时候,相当于执行了kill(进程号,SIGKILL)

1.4 sigaction函数

百度了解一下

1.5 利用sigchld信号避免僵尸进程

      SIGCHLD信号的编号

该信号的功能是,当进程结束时,会向其父进程发生该信号。通过这个原理,我们可以避免僵尸进程。

 

运行结果:

 

解析:

问题:

如果子进程通过exit(0)正常退出呢?

执行结果

结论:没有区别!

 

如果父进程调用了wait函数呢?

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

下家山

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值