Chinaunix首页 | 论坛 | 博客
  • 博客访问: 147364
  • 博文数量: 23
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 326
  • 用 户 组: 普通用户
  • 注册时间: 2014-02-26 10:49
个人简介

记忆总是会慢慢褪去,所以让文字记住一切~

文章分类

全部博文(23)

文章存档

2017年(5)

2016年(3)

2015年(9)

2014年(6)

我的朋友

分类: LINUX

2015-08-27 09:37:08

这两天Coding结束了,闲了一点,写篇博文吧......刚好这次做的一个模块用到了信号处理机制,所以就写写这个吧~
Linux的系统上,经常会听到说给某某进程发个信号,让它来做什么什么样的事情。刚好之前项目中用到这个技巧,所以就简单写篇文章记录一下,便于大家学习。

简单的调用可以在shell中调用kill –X PID,其实kill有多个参数,可以man一下。这里X即为信号值,其实类似于一个号码(kill –l可列出来系统支持的所有信号)。可以看到kill –l列出的数据一般都是SIGXXX,当我们在shell脚本中使用时,最好将前面的“SIG”去掉,这样可以减少系统的兼容性问题,或者我们使用相应的编号号码来作为参数。PID是实际运行在系统上的进程号。可以用ps命令来获得。

我们可以让程序来捕获信号,并设定对应的处理程序,这样可以让程序做更多的事情。关于信号对应的处理函数设置可以参照APUE这本书,其核心思想包括两步骤:

a)  定义信号处理函数,其原型为: void sig_handler(int sig);

b)  设置信号对应的处理函数,可以使用signal()来设定,或其他类似方法。

 

好了说道这里,给进程发送信号究竟可以做什么呢?这里根据我的经验列出了下面4个使用场景:

1)  强行退出进程

使用的是kill -9 pid9SIGKILL的编号。这个我想大部分人都会使用。

2)  优雅的退出进程

因为在1)中的SIGKILL这个信号不可以被我们捕捉,所以我们无法给出相应的信号处理函数。那么我们可以通过捕捉其他信号,加上对应的处理函数来完成进程的退出,这样样可以更加优雅的退出。这一般会在有需求的情况下这么做,比如在退出之前我们需要保存或清理一些数据。

3)  重启部分进程

当我们讨论重启时,心中的第一种思路就是杀死一个进程然后再重新执行程序。其实我们也可以不杀死一个进程来进行一些需要的重启。这种情况一般使用在多进程的情况下,一个master下面有多个children进程。在一些情况下我们可能需要去关闭无用的children进程,并通过fork来创建拥有新能力的新进程。这个时候就可以通过这种方法,master来接受信号,并设置一些属性功能。这点有点类似nginx最初的管理模式。

4)  加载配置

我想这个用得应该比较多,当我们对于一个程序的设定改变时,不想重启这个进程(因为重启的花销实在太大了,特别对于关键服务的进程)。那就只能想个法子让进程来读取新的设定。一种方法是:我们可以在进程中启动一个线程来定时的观察设置有没有改变,一旦改变就加载一下。这种方法的缺点是有一个线程的存在,多少会消耗一点系统资源。第二种方法:设定一个信号并对应着加载设定的处理程序(一般称之为reload),这样当程序捕捉到这样的信号即去读取新的设置,触发式的总感觉好一点,不会浪费太多资源。


以上
4中场景是在我们项目中经常用到的,供大家参考,希望对你有所帮助~~

阅读(1790) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~