linux中的两个非常重要的信号:SIGALRM信号和SIGCHID信号

在进行阻塞式系统调用时,为避免进程陷入无限期的等待,可以为这些阻塞式系统调用设置定时器。Linux提供了alarm系统调用和SIGALRM信号实现这个功能。

要使用定时器,首先要安装SIGALRM信号。如果不安装SIGALRM信号,则进程收到SIGALRM信号后,缺省的动作就是终止当前进程。SIGALRM信号安装成功后,在什么情况下进程会收到该信号呢?这就要依赖于Linux提供的定时器功能。在Linux系统下,每个进程都有惟一的一个定时器,该定时器提供了以秒为单位的定时功能。在定时器设置的超时时间到达后,调用alarm的进程将收到SIGALRM信号。alarm系统调用的原型为:

#include <unistd.h>

unsigned int alarm(unsigned int seconds);

参数说明:

1)seconds:要设定的定时时间,以秒为单位。在alarm调用成功后开始计时,超过该时间将触发SIGALRM信号。

返回值:

返回当前进程以前设置的定时器剩余秒数。

例8-10:编程利用SIGALRM信号实现秒定时器。

代码如下:

#include <stdio.h>

#include <signal.h>

//全局计数器变量

int Cnt=0;

//SIGALRM信号处理函数

void CbSigAlrm(int signo)

{

//输出定时提示信息

printf("   seconds: %d",++Cnt);

printf("\r");

//重新启动定时器,实现1秒定时

alarm(1);

}

void main()

{

//安装SIGALRM信号

if(signal(SIGALRM,CbSigAlrm)==SIG_ERR)

{

perror("signal");

return;

}

//关闭标准输出的行缓存模式

setbuf(stdout,NULL);

//启动定时器

alarm(1);

//进程进入无限循环,只能手动终止

while(1)

{

//暂停,等待信号

pause();

}

}

8.5.2 SIGCLD信号

在Linux的多进程编程中,SIGCLD是一个非常重要的信号。当一个子进程退出时,并不是立即释放其占用的资源,而是通知其父进程,由父进程进行后续的工作。在这一过程中,系统将依次产生下列事件。

1)向父进程发送SIGCLD信号,子进程进入zombie(僵尸)状态。

2)父进程接收到SIGCLD信号,进行处理。

如果在上述过程中父进程既没有忽略SIGCLD信号,也未捕获该信号进行处理,则子进程将进入僵尸状态。僵尸状态的进程不能被操作系统调用,也没有任何可执行代码,它不过是占用了进程列表中的一个位置而已。如果仅有几个僵尸进程不会影响系统的运行,但是如果僵尸进程过多,则将会严重影响系统的运行。因此,在编程过程中应避免产生僵尸进程。有两种基本的处理方法可以避免产生僵尸进程:一是父进程忽略SIGCLD信号;二是父进程捕获SIGCLD信号,在信号处理函数中获取子进程的退出状态。忽略信号的方式比较简单,只需要调用signal(SIGCLD,SIG_IGN)语句即可完成。如果要捕获信号并处理,那么先要安装SIGCLD信号,然后在信号处理函数中调用wait或者waitpid等函数获取子进程的退出状态。

例8-11:编程捕获SIGCLD信号,输出各子进程的ID和退出状态码。

代码如下:

#include <stdio.h>

#include <stdlib.h>

#include <signal.h>

//SIGCLD信号处理函数

void CbSigCld(int signo)

{

//保存退出进程的ID

int pid;

//保存退出进程的退出状态码

int status;

//等待任何一个子进程退出

pid=waitpid(-1,&status,0);

//输出退出的子进程ID和退出代码

printf("Child process %d exit with status %d\n",pid,status);

}

void main()

{

int i,pid;

//安装SIGCLD信号

if(signal(SIGCLD,CbSigCld)==SIG_ERR)

{

perror("signal");

return;

}

//循环创建子进程

for(i=0;i<5;i++)

{

pid=fork();

//如果是子进程

if(pid==0)

{

//退出子进程,退出状态码为0

exit(0);

}

//如果是父进程

else

{

sleep(1);

}

}

}

linux中的两个非常重要的信号:SIGALRM信号和SIGCHID信号

时间: 2024-10-16 14:44:40

linux中的两个非常重要的信号:SIGALRM信号和SIGCHID信号的相关文章

Linux中的两种link方式

Linux系统中包括两种链接方式:硬链接(hard link)和符号链接(symbolic link),其中符合链接就是所谓的软链接(soft link),那么两者之间到底有什么区别呢? inode 在Linux系统中,内核为每一个新创建的文件分配一个inode,每个文件都有一个惟一的inode,这里将inode简单理解成一个指针,它永远指向本文件的具体存储位置同时,文件属性保存在inode里,比如owner等.在访问文件时,inode被复制到内存,从而实现文件的快速访问.系统是通过inode来

Linux中的两种守护进程stand alone和xinetd

--http://www.cnblogs.com/itech/archive/2010/12/27/1914846.html#top 一般使用stand alone /etc/init.d/ 非常少用xinetd /etc/xinetd.d/ Linux守护进程的运行方式 1.独立运行(stand-alone)的守护进程 独立运行的守护进程由init脚本负责管理,所有独立运行的守护进程的脚本在/etc/rc.d/init.d/目录下.系统服务都是独立运行的守护进程,包括syslogd和cron等

Linux中的两个经典宏定义:获取结构体成员地址,根据成员地址获得结构体地址;Linux中双向链表的经典实现。

倘若你查看过Linux Kernel的源码,那么你对 offsetof 和 container_of 这两个宏应该不陌生.这两个宏最初是极客写出的,后来在Linux内核中被推广使用. 1. offsetof 1.1 offsetof介绍 定义:offsetof在linux内核的include/linux/stddef.h中定义.#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) 说明:获得结构体(TYPE)的变量成员(

Linux中对两文件处理

介绍三个命令 1.{sort}   可以对文件中的数据进行排序,并将结果显示在标准输出上 2.{uniq}   可以将重复的行从输出中删除,只留下唯一样本 3.{diff}   逐行对比两个文件,列出不同之处. 当我们出来文件时,通常会碰到难以处理的文件,比如说对比两个文件进行比较,找出不同之处 三要素:sort我排序 uniq我去重 diff我比较  diff3(对三个文件进行比较) sort filename uniq filename diff filename  -y 并排格式输出. d

Linux中的Makefile

在Linux中Makefile扮演一个非常重要的角色,我们可以以Linux为平台在上面编写我们需要的C程序代码, 对于C语言来说,Linux是一个非常好的平台来学习.使用.调试.验证C代码的平台,其强大的Vim编辑器,还 有强大的gcc编译工具和gdb的调试工具,对于我们学习C语言都是一个非常重要的工具,我们可以非常清晰的看 清C语言代码的执行过程,可以通过gdb调试工具观察代码的执行方法等等优点,我在这就不一一列举了. 使用 sp max.c   建立一个新的文件: gcc编译工具: I(i)

Linux中的who系列命令who/whoami/who am i

在Linux中who系列命令存在who/whoami/who am i. 首先我已普通用户guixian001等了系统.然后执行命令分别执行命令whoami/who am i/who.截图如下: 然后我们使用su命令切换到root用户再执行以上三个命令. 看出区别了吗?使用whoami命令显示的是当前"操作用户"的用户名.而who am i显示的是"登录用户"的用户名.要解释这个现象需要引入linux中的两个概念--实际用户(UID,即user id)和有效用户(E

浅析Linux中的信号机制(一)

有好些日子没有写博客了,自己想想还是不要荒废了时间,写点儿东西记录自己的成长还是百利无一害的.今天是9月17号,暑假在某家游戏公司实习了一段时间,做的事情是在Windows上用c++写一些游戏英雄技能的逻辑实现.虽然时间不算长,但是也算学了一点东西,对团队项目开发流程也有了一个直观的感受,项目里c++11新特性也有用到不少,特别是lambda表达式,STL的一些容器和算法也终于有了可以实践的地方.由于自己比较喜欢Linux C,也就没有做留下的打算,现在回到了学校,好好复习一段时间,准备一下校招

浅谈Linux中的信号机制(二)

首先谢谢 @小尧弟 这位朋友对我昨天夜里写的一篇<浅谈Linux中的信号机制(一)>的指正,之前的题目我用的“浅析”一词,给人一种要剖析内核的感觉.本人自知功力不够,尚且不能对着Linux内核源码评头论足.以后的路还很长,我还是一步一个脚印的慢慢走着吧,Linux内核这座山,我才刚刚抵达山脚下. 好了,言归正传,我接着昨天写下去.如有错误还请各位看官指正,先此谢过. 上篇末尾,我们看到了这样的现象:send进程总共发送了500次SIGINT信号给rcv进程,但是实际过程中rcv只接受/处理了1

细说Linux中的信号(signal )

在细说信号之前我们先来了解下什么是信号.信号(signal)是一种软件中断,它提供了一种处理异步事件的方法,也是进程间惟一的异步通信方式.在Linux系统中,根据POSIX标准扩展以后的信号机制,不仅可以用来通知某种程序发生了什么事件,还可以给进程传递数据. 信号的种类有很多,我们可以通过kill -l命令察看系统定义的信号列表: 可以看到一共有62个信号.1-31号为普通信号:34-64号为实时信号.(博主这次只讨论普通信号.) 接下来我们来细说信号的产生.阻塞和捕捉. >>信号的产生: 通