Linux信号signal的介绍和示例

 

如何让程序在后台运行

       在之前的章节中,如果要运行程序,在命令提示行下输入程序名后回车,程序被执行,然后等待程序运行完成。在程序运行的过程中,可以用Ctrl+c中止它。

       在实际开发中,我们需要让程序在后台运行,不受界面的影响,也不让程序员等待,例如前几章节的socket服务端程序。

       如果想让程序在后台运行,有两种方法。

1、加“&”符号

       如果想让程序在后台运行,执行程序的时候,命令的最后面加“&”符号。

       如:

       ./book242 &

       程序就在后台运行了。

      

       在后台运行的程序,用Ctrl+c无法中断,并且就算终端退出了,程序仍在后台运行。

       如果终端退出了,后台运行的程序将由系统托管。

     

       在第一张图中,book249的父进程是4555,第二张图中,book249的父进程是1。

2、采用fork

       另一种方法是采用fork,主程序执行fork,生成一个子进程,然后父进程退出,留下子进程继续运行,子进程将由系统托管。

       示例:

      

       上图中,突出显示的就是新增的代码。

      

       上图中,子进程的父进程是系统进程。

3、如何让中止后台程序

       问题来了,程序在后台运行了,离开了终端控制,用Ctrl+c上也无法中止,那怎么让它停下来呢?暂时用一个笨方法:杀了它。

       杀程序有两个方法:

       1)killall 程序名

              killall book249

       2)先用“ps -ef|grep 程序名”找到程序的进程编号,然后用“kill 进程编号”

      

signal信号

       signal信号是Linux编程中非常重要的部分,接下来将详细介绍信号机制的基本概念、Linux对信号的实现和使用,以及有关信号的几个系统调用(库函数)。

       signal信号是进程之间相互传递消息的一种方法,信号全称为软中断信号,也有人称作软中断。从它的命名可以看出,它的实质和使用很象中断。信号是进程控制的一部分。

1、信号的基本概念 

       软中断信号(signal,又简称为信号)用来通知进程发生了事件。进程之间可以通过调用kill库函数发送软中断信号。内核也可以因为内部事件而给进程发送信号,通知进程发生了某个事件。注意,信号只是用来通知某进程发生了什么事件,并不给该进程传递任何数据。 

       收到信号的进程对各种信号有不同的处理方法。处理方法可以分为三类:第一种是类似中断的处理程序,对于需要处理的信号,进程可以指定处理函数,由该函数来处理。第二种方法是,忽略某个信号,对该信号不做任何处理,就象未发生过一样。第三种方法是,对该信号的处理保留系统的默认操作,大部分的信号的默认操作是终止进程。

2、信号的类型 

       发出信号的原因很多,这里按发出信号的原因简单分类,以了解各种信号:

信号名

信号值

默认处

理动作

发出信号的原因

SIGHUP

1

A

终端挂起或者控制进程终止

SIGINT

2

A

键盘中断Ctrl+c

SIGQUIT

3

C

键盘的退出键被按下

SIGILL

4

C

非法指令

SIGABRT

6

C

由abort(3)发出的退出指令

SIGFPE

8

C

浮点异常

SIGKILL

9

AEF

采用kill -9 进程编号 强制杀死程序。

SIGSEGV

11

C

无效的内存引用

SIGPIPE

13

A

管道破裂:写一个没有读端口的管道

SIGALRM

14

A

由alarm(2)发出的信号

SIGTERM

15

A

采用“kill 进程编号”或“killall 程序名”通知程序。

SIGUSR1

30,10,16

A

用户自定义信号1

SIGUSR2

31,12,17

A

用户自定义信号2

SIGCHLD

20,17,18

B

子进程结束信号

SIGCONT

19,18,25

 

进程继续(曾被停止的进程)

SIGSTOP

17,19,23

DEF

终止进程

SIGTSTP

18,20,24

D

控制终端(tty)上按下停止键

SIGTTIN

21,21,26

D

后台进程企图从控制终端读

SIGTTOU

22,22,27

D

后台进程企图从控制终端写

       处理动作一项中的字母含义如下

       A 缺省的动作是终止进程。

       B 缺省的动作是忽略此信号,将该信号丢弃,不做处理。

       C 缺省的动作是终止进程并进行内核映像转储(core dump),内核映像转储是指将进程数据在内存的映像和进程在内核结构中的部分内容以一定格式转储到文件系统,并且进程退出执行,这样做的好处是为程序员 提供了方便,使得他们可以得到进程当时执行时的数据值,允许他们确定转储的原因,并且可以调试他们的程序。

       D 缺省的动作是停止进程,进入停止状况以后还能重新进行下去。

       E 信号不能被捕获。

       F 信号不能被忽略。

3、signal库函数 

       signal库函数可以设置程序对信号的处理方式。

       包含头文件:

              #include <signal.h> 

       函数声明:

              sighandler_t signal(int signum, sighandler_t handler);

       参数signum表示信号的编号。

       参数handler表示信号的处理方式,有三种情况:

       1)SIG_IGN:忽略参数signum所指的信号。

       2)一个自定义的处理信号的函数,信号的编号为这个自定义函数的参数。

       3)SIG_DFL:恢复参数signum所指信号的处理方法为默认值。 

       程序员不关心signal的返回值。

4、信号有什么用

       服务程序运行在后台,如果想让它中止,杀了它不是个好办法,因为程序被杀的时候,程序突然死亡,没有释放资源,会影响系统的稳定。还有,用Ctrl+c与杀程序是相同的效果。

       如果能向后台程序发送一个信号,后台程序收到这个信号后,调用一个函数,在函数中编写释放资源的代码,程序就可以有计划的退出,安全而体面。

       信号还可以用于服务程序抓包等,这是较复杂的应用,暂时不介绍。

5、示例 

       在实际开发中,在main函数开始的位置,程序员会先屏蔽掉全部的信号。

              for (int ii=0;ii<50;ii++) signal(ii,SIG_IGN);

       这么做的目的是不希望程序被干扰。然后,再设置程序员关心的信号的处理函数。

       程序员关心的信号有三个:SIGINT、SIGTERM和SIGKILL。

       程序在运行中,如果按Ctrl+c,将向程序发出SIGINT信号,信号编号是2。

       采用“kill 进程编号”或“killall 程序名”向程序发出的是SIGTERM信号,编号是15。

       采用“kill -9 进程编号”向程序发出的是SIGKILL信号,编号是9,此信号不能被忽略,也无法捕获,程序将突然死亡。

       所以,程序员只要设置SIGINT和SIGTERM两个信号的处理函数就可以了,这两个信号可以使用同一个处理函数,函数的代码是释放资源。

       以下只截取与信号有关的部分代码。

      

       运行结果

      

       不管是用Ctrl+c还是kill,程序都能体面的退出。

发送信号

       Linux操作系统提供了kill命令向程序发送信号,C语言也提供了kill库函数,用于在程序中向其它进程或者线程发送信号。

       函数声明:

              int kill(pid_t pid, int sig);

       kill函数将参数sig指定的信号给参数pid 指定的进程。

       参数pid 有几种情况:

       1)pid>0 将信号传给进程识别码为pid 的进程。

       2)pid=0 将信号传给和目前进程相同进程组的所有进程,常用于父进程给子进程发送信号。

       3)pid=-1 将信号广播传送给系统内所有的进程,例如系统关机时,会向所有的登录窗口广播关机信息。

       sig:准备发送的信号代码,假如其值为零则没有任何信号送出,但是系统会执行错误检查,通常会利用sig值为零来检验某个进程是否仍在运行。

       返回值说明: 成功执行时,返回0;失败返回-1,errno被设为以下的某个值。

       EINVAL:指定的信号码无效(参数 sig 不合法)。

       EPERM:权限不够无法传送信号给指定进程。

       ESRCH:参数 pid 所指定的进程或进程组不存在。

 

版权声明

C语言技术网原创文章,转载请说明文章的来源、作者和原文的链接。

来源:C语言技术网(www.freecplus.net

作者:码农有道

如果这篇文章对您有帮助,请点赞支持,或在您的博客中转发我的文章,谢谢!!!

如果文章有错别字,或者内容有误,或其他的建议或意见,请您留言指正,非常感谢!!!

 

 

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

C语言技术网-码农有道

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

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

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

打赏作者

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

抵扣说明:

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

余额充值