三十一、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,进程的终止状态,以及该 ...
随机推荐
- [NOI2018]你的名字(后缀自动机+线段树)
题目描述 小A 被选为了ION2018 的出题人,他精心准备了一道质量十分高的题目,且已经把除了题目命名以外的工作都做好了. 由于ION 已经举办了很多届,所以在题目命名上也是有规定的,ION 命题手 ...
- Freescale 车身控制模块(BCM) 解决方案
中国汽车业已成为全球第一市场,标志着中国汽车产业进入了白热化竞争时代,因此,人们对汽车的操控性,安全性,易用性,舒适性,以及智能化要求也越来越高,更大的空间需求和更多的零部件因而产生了冲突,这就要求汽 ...
- MongoDB查询内嵌数组(限定返回符合条件的数组中的数据)(1)
https://blog.csdn.net/bicheng4769/article/details/79579830 项目背景 最近在项目中使用mongdb来保存压测结果中的监控数据,那么在获取监控数 ...
- JavaScrip相关知识总结
1.javascript是一种基于对象的语言,其中有四个常用的“全局对象”的成员使用,因为没有“全局对象关键字global”而直接使用,所以感觉像违背了JavaScript基于对象编程的原则,但其实是 ...
- 为什么 管理工具里没有Internet(IIS)管理器选项
如上图,localhost页能打开了,但是管理工具里没有iis管理器,主要原因是安装iis时候没有选择web管理工具,选取安装上就 有了
- Redis在python中的使用
一 简介 redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(sorted ...
- python简单购物车改进版
# -*- coding: utf-8 -*- """ ┏┓ ┏┓ ┏┛┻━━━┛┻┓ ┃ ☃ ┃ ┃ ┳┛ ┗┳ ┃ ┃ ┻ ┃ ┗━┓ ┏━┛ ┃ ┗━━━┓ ┃ 神 ...
- MySQL填充字符串函数 LPAD(str,len,padstr),RPAD(str,len,padstr)
转: MySQL填充字符串函数 LPAD(str,len,padstr),RPAD(str,len,padstr) LPAD(str,len,padstr) 用字符串 padstr对 str进行左边填 ...
- 二叉查找树(BST)、平衡二叉树(AVL树)(只有插入说明)
二叉查找树(BST).平衡二叉树(AVL树)(只有插入说明) 二叉查找树(BST) 特殊的二叉树,又称为排序二叉树.二叉搜索树.二叉排序树. 二叉查找树实际上是数据域有序的二叉树,即对树上的每个结点, ...
- QT:基本知识(一);
注: 该博文为扩展型: 1) QString转换为LPCTSTR QString szStr; LPCTSTR str = (LPWSTR)(szStr.utf16()); 2) 中文 ...