三十一、Linux 进程与信号——SIGCHLD 信号、kill和raise函数以及alarm函数
31.1 SIGCHLD 信号
- 子进程状态发生变化(子进程结束)产生该信号,父进程需要使用 wait 调用来等待子进程结束并回收它。
- 避免僵尸进程
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/wait.h>
#include <unistd.h> void sig_handler(int signo)
{
printf("child process deaded, signo: %d\n", signo); /** 当父进程捕获到 SIGCHLD 信号后要调用 wait
* 函数去回收子进程,否则子进程会成为僵尸进程 */
wait();
} void out(int n)
{
int i;
for(i = ; i < n; i++) { printf("%d out %d\n", getpid(), i);
sleep();
}
} int main(void)
{
if(signal(SIGCHLD, sig_handler)){
perror("signal sigchld error");
} pid_t pid = fork();
if(pid < ) { perror("fork error");
exit();
} else if(pid > ) {
/** parent process */
out();
} else {
/** child process */
out();
} return ;
}
31.2 信号发送
- 除了内核和超级用户,并不是每个进程都可以向其他的进程发送信号
- 一般的进程只能向具有相同 uid 和 gid 的进程发送信号,或向相同进程组中的其他进程发送信号
- 常用的发送信号的函数由 kill()、raise()、alarm()、settitimer()、abort()等。
31.2.1 kill() 函数 和 raise() 函数
#include <signal.h>
int kill(pid_t pid, int signo);
- 函数功能:向指定的进程发送某一个信号
- 函数参数:
- pid:接受信号进程的 pid
- pid > 0 将信号发给进程 ID 为 pid 的进程
- pid == 0 将信号发给与发送进程同一进程组的所有进程
- pid < 0 将该信号发送给进程组 ID 等于 pid 的绝对值
- pid == -1 将该信号发送给发送进程有权限向他们发送信号的系统上的所有进程
- signo:要发送的信号值
- pid:接受信号进程的 pid
- 返回值:成功返回0,出错返回 -1
- 说明:kill 函数将信号发送给进程或进程组
- 0 为空信号,常用来检测特定的进程是否存在
#include <signal.h>
int raise(int signo);
- 函数功能:向进程本身发送一个信号,相当于 kill(getpid(), sig)
- 函数参数:
- signo:要发送的信号值
- 返回值:成功返回0,出错返回 -1
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h> #define KILLSELF 0 /** 定义信号处理函数
* signo 进程捕获到的信号
*/
void sig_handler(int signo)
{
printf("%d, %d occured\n", getpid(), signo);
} int main(void)
{
/** 向内核登记信号处理函数以及信号值 */
if(signal(SIGTSTP, sig_handler) == SIG_ERR) {
perror("signal sigtstp error");
} if(signal(SIGINT, sig_handler) == SIG_ERR) {
perror("signal sigint error");
} if(signal(SIGUSR1, sig_handler) == SIG_ERR) {
perror("signal usr1 error");
} if(signal(SIGUSR2, sig_handler) == SIG_ERR) {
perror("signal usr2 error");
}
/*
if(signal(SIGKILL, SIG_IGN) == SIG_ERR) {
perror("signal sigtstp error");
} if(signal(SIGSTOP, SIG_IGN) == SIG_ERR) {
perror("signal sigint error");
}
*/
int i = ;
while(i < ) {
printf("%d out %d\n", getpid(), i++);
if(i == ) {
#ifdef KILLSELF
kill(getpid(), SIGKILL);
#endif
sleep();
}
sleep();
} /** 向进程自己发送 SIGUSR1 和SIGUSR2 信号 */
raise(SIGUSR1);
kill(getpid(), SIGUSR2);
return ;
}
31.2.2 alarm() 函数
#include <unistd.h>
unsigned int alarm(unsigned int seconds);
- 函数说明:
- alarm 函数可设置定时器,当定时器超时,产生 SIGALRM 信号
- 信号由内核产生,在指定的 seconds 秒之后,给进程本身发送一个 SIGALRM 信号。
- 参数为 0,取消以前设置的定时器
- 返回值:
- 0 或以前设置的定时器时间余留秒数
#include <signal.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h> void sig_handler(int signo)
{
if(SIGALRM == signo) {
printf("clock time out\n");
alarm(); ///< 重新设置定时器(周期性的定时)
}
} void out_data(void)
{
int i = ;
while(i <= ) {
double d = drand48();
printf("%-10d: %lf\n", i++, d);
if(i == )
alarm(); ///< 取消定时器
sleep(1);
}
} int main(void)
{
if(signal(SIGALRM, sig_handler) == SIG_ERR) {
perror("signal sigalrm error");
} // 设置定时器
alarm();
printf("begin running main\n");
out_data();
printf("end running main\n");
return ;
}
三十一、Linux 进程与信号——SIGCHLD 信号、kill和raise函数以及alarm函数的更多相关文章
- 《linux 进程管理》- ps/top/kill/nice
一:进程简述 二:ps 查看进程 语法 ps * -A 列出所有进程,和 -e 同等效果 * -a 列出不和本终端有关系的所有进程 * -w 显示加宽,可以显示较多信息 * -u 显示有效使用者相关的 ...
- 信号的发送kill,raise,alarm,setitimer,abort,sigqueue
1.kill函数 int kill(pid_t pid, int sig); 发送信号给指定的进程. (1) If pid is positive, then signal sig is sent t ...
- (三)Linux Shell编程——Shell常用命令(输出、判断、循环、函数、包含)
3. 常用命令 3.1 输出 3.1.1 echo命令 echo是Shell的一个内部指令,用于在屏幕上打印出指定的字符串.命令格式: echo arg name="coding" ...
- 实验三:Linux进程管理(HDU)
2.设计内容 把下面的几个网址的内容看懂,关于Linux的通信机制就会有个基本的了解了,后面的这几个代码也应该可以看得懂了. 管道通信:https://blog.csdn.net/ljianhui/a ...
- linux下的僵尸进程处理SIGCHLD信号
什么是僵尸进程? 首先内核会释放终止进程(调用了exit系统调用)所使用的所有存储区,关闭所有打开的文件等,但内核为每一个终止子进程保存了一定量的信息.这些信息至少包括进程ID,进程的终止状态,以及该 ...
- [转] linux下的僵尸进程处理SIGCHLD信号
什么是僵尸进程? 首先内核会释放终止进程(调用了exit系统调用)所使用的所有存储区,关闭所有打开的文件等,但内核为每一个终止子进程保存了一定量的信息.这些 信息至少包括进程ID,进程的终止状态,以及 ...
- linux下的僵尸进程处理SIGCHLD信号【转】
转自:http://www.cnblogs.com/wuchanming/p/4020463.html 什么是僵尸进程? 首先内核会释放终止进程(调用了exit系统调用)所使用的所有存储区,关闭所有打 ...
- 第9章 Linux进程和信号超详细分析
9.1 进程简单说明 进程是一个非常复杂的概念,涉及的内容也非常非常多.在这一小节所列出内容,已经是我极度简化后的内容了,应该尽可能都理解下来,我觉得这些理论比如何使用命令来查看状态更重要,而且不明白 ...
- 僵尸进程与SIGCHLD信号
什么是僵尸进程? 首先内核会释放终止进程(调用了exit系统调用)所使用的所有存储区,关闭所有打开的文件等,但内核为每一个终止子进程保存了一定量的信息.这些信息至少包括进程ID,进程的终止状态,以及该 ...
随机推荐
- Linux的wget命令详解【转载】
Linux wget是一个下载文件的工具,它用在命令行下.对于Linux用户是必不可少的工具,尤其对于网络管理员,经常要下载一些软件或从远程服务器恢复备份到本地服务器.如果我们使用虚拟主机,处理这样的 ...
- limits.conf文件工作原理
1. limits.conf 描述 limits.conf文件实际是Linux PAM(插入式认证模块,Pluggable Authentication Modules)中 pam_limits.so ...
- mybatis的一种批量更新方法【我】
接手一个项目,项目主要架构用的 servlet 3.0 + spring + mybatis 其中发现一个问题: 操作数据时,批量插入可以,批量更新,使用各种写法都无法成功,直接报 mybatis转换 ...
- 马士兵2string buffuer
string不可变的字符序列 s1=s1+s2
- jquery 获取$("#id").text()里面的值 需要进行去空格去换行符操作
Jquery:$("#accuracy").val($("#accuracy").val().replace(/\ +/g,""));//去 ...
- 利用sys打印进度条
在很多常见中,需要对当前处理的进度进行显示,这个时候就需要进度条了,在python中,也有封装好的进度条模块,当然,也可以自己编写一个简单的进度条来帮助理解进度条的实现. 首先,需要理解一个概念,就是 ...
- jdk1.8的新特性:很全面
JDK1.8: https://www.cnblogs.com/tiantianbyconan/p/3613506.html stream的几个方法: filter: 过滤条件 过滤为空的方法: 刚好 ...
- java基础入门-语法(1)
因为平时用到一些java的项目,比如ElasticSearch,zookeeper等,有时也想看看里面怎么实现的,或者看到别人分析原理时候会用到java源码, 自己也想跟着学一下,最起码能看懂别人的分 ...
- C++: 可变参数;
可变参数,即参数的个数是动态变化的, 可多可少. 1. 可变参数: 可变参数一般采用”..."表示,用在宏上表示变参宏, 如: #define WriteLine(format,...) p ...
- JavaSE_坚持读源码_Object对象_Java1.7
/** * Returns a hash code value for the object. This method is * supported for the benefit of hash t ...