三十一、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,进程的终止状态,以及该 ...
随机推荐
- SSH出现Connection refused错误
笔者在使用ssh localhost时出现Connection refused提示,初步判断是22端口未开启服务,也有可能是防火墙未正确配置. 测试 使用netstat | grep 22测试,发现2 ...
- 中性SNP的突变年龄评估(estimate the average age of a neutral two-allele polymorphism)
假设中性突变的频率分别为P和1-P,则其突变年龄为:-4Ne[p*( logep)+(1-p)* loge (1-p)] The average age of a neutral two-allele ...
- GUI 设计
GUI(图形化界面编程) Graphical User Interface (java.Awt javax.Swing) CLI(命令行操作接口) Command line User ...
- Codeforce 886 Технокубок 2018 - Отборочный Раунд 3 C. Petya and Catacombs(结论题)
A very brave explorer Petya once decided to explore Paris catacombs. Since Petya is not really exper ...
- glob.glob 匹配文件
glob.glob以列表形式返回匹配的文件路径 只有一个参数:文件的匹配规则 e.g. >>>res_home = '/vip_data_center/test_envs/train ...
- jquery的checked以及disabled
下面只提到checked,其实disabled在jquery里的用法和checked是一模一样的 下边两种写法没有任何区别 只是少了些代码而已... ------------------------- ...
- Luogu P4551 最长异或路径
题目链接 \(Click\) \(Here\) \(01Trie\)好题裸题. 取节点\(1\)为根节点,向下扫每一个点从根节点到它路径上的异或和,我们可以得到一个\(sumx[u]\). 现在路径异 ...
- (线段判交的一些注意。。。)nyoj 1016-德莱联盟
1016-德莱联盟 内存限制:64MB 时间限制:1000ms 特判: No通过数:9 提交数:9 难度:1 题目描述: 欢迎来到德莱联盟.... 德莱文... 德莱文在逃跑,卡兹克在追.... 我们 ...
- PHP-FIG - PHP 标准规范
转自:https://psr.phphub.org/ PHP 标准规范 PSR 是 PHP Standard Recommendations 的简写,由 PHP FIG 组织制定的 PHP 规范,是 ...
- 给笔记本更换SSD硬盘
给笔记本更换SSD硬盘... ---------- 给笔记本更换SSD硬盘 带活动字样的一个新的系统盘,一个之前的主分区的系统盘 ----------------------------