在进行堵塞式系统调用时。为避免进程陷入无限期的等待,能够为这些堵塞式系统调用设置定时器。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信号的更多相关文章

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

    Linux中的两种守护进程stand alone和xinetd --http://www.cnblogs.com/itech/archive/2010/12/27/1914846.html#top 一 ...

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

    倘若你查看过Linux Kernel的源码,那么你对 offsetof 和 container_of 这两个宏应该不陌生.这两个宏最初是极客写出的,后来在Linux内核中被推广使用. 1. offse ...

  3. linux中的两个命令setfacl和chmod有什么区别

    setfacl命令可以用来细分linux下的文件权限.chmod命令可以把文件权限分为u,g,o三个组,而setfacl可以对每一个文件或目录设置更精确的文件权限. 比较常用的用法如下:setfacl ...

  4. Linux中一些 不是很常用的配置修改

    1,让虚拟机屏幕最大化 :查看-->自动调整大小-->自动适应客户机 2,让虚拟机取消屏保: system --> preferences --> Screensaver

  5. linux中删除目录

    在linux中删除一个目录很简单,很多人还是习惯用rmdir,不过一旦目录非空,就陷入深深的苦恼之中,现在使用rm -rf命令即可解决. 直接rm就可以了,不过要加两个参数-rf 即:rm -rf 目 ...

  6. linux中的vi编辑器(一)

    1.在linux中如果两个用户都在打开一个文件进行编辑,那么文件最后将以最后保存的版本为主. 2.vi仅仅是一个文本编辑器,相当于windows中的记事本,vi的工作模式, 命令模式:在该模式下,在键 ...

  7. linux初级学习笔记二:linux操作系统及常用命令,文件的创建与删除和命名规则,命令行展开以及linux中部分目录的作用!(视频序号:02_3)

    本节学习的命令:tree,mkdir,rmdir,touch,stat,rm 本节学习的技能:Linux中主要的目录作用以及特殊的目录文件: 文件的命名规则,命令行展开: 文件的创建与删除: Linu ...

  8. linux 中的进程wait()和waitpid函数,僵尸进程详解,以及利用这两个函数解决进程同步问题

    转载自:http://blog.sina.com.cn/s/blog_7776b9d3010144f9.html 在UNIX 系统中,一个进程结束了,但是他的父进程没有等待(调用wait / wait ...

  9. linux环境中,两个不同网段的机器互通

    linux环境中,两个不同网段的机器互通   人评论3690人阅读2019-11-18 14:50:21   环境如下:   host1 单网卡 eth0 172.24.100.15/16   hos ...

随机推荐

  1. 反编译apk 修改 合成

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha 反编译apk帮助文档 准备工具 dex2jar(dex转换jar工具),下载地址: ht ...

  2. [BZOJ2007][NOI2010]海拔(对偶图最短路)

    首先确定所有点的海拔非0即1,问题转化成裸的平面图最小割问题,进而转化成对偶图最短路(同BZOJ1002). 这题的边是有向的,所以所有边顺时针旋转90度即可. 如下图(S和T的位置是反的). #in ...

  3. 【最短路】【spfa】CDOJ1647 酌贪泉而觉爽, 处涸辙以犹欢。

    题意: 给你一个全为0的01串,问你能否通过一系列的变换,得到全为1的01串. 分析: 将每个01串看作一个点,每一个变换可以看作是一条有向边,现在问题可以转化 为找从“00..0”这个点到“11.. ...

  4. 【深度优先搜索】mr353-取奶

    应该是USACO的题目,暂时没有找到对应出处. [题目大意] 农夫约翰要量取 Q(1 <= Q <= 20,000)夸脱(夸脱,quarts,容积单位——译者注) 他的最好的牛奶,并把它装 ...

  5. Android——Activity and Service

    参考博客:http://www.cnblogs.com/newcj/archive/2011/05/30/2061370.html   http://www.cnblogs.com/feisky/ar ...

  6. fedora19/opensuse13.1 配置openvpn client

    Date: 20140207Auth: Jin 1.install # yum -y install openvpn #zypper install openvpn 2.copy user key # ...

  7. CentOS 6.9下iptables通过raw表实现日志输出和调试

    说明:iptables调试的最好方式应该是输出日志了.并且iptables有个raw的表,优先级别最好,且调试时针对icmp协议(ping)进行,那么日志输出就是整条链路串起来输出的,非常的清晰. 前 ...

  8. Ubuntu 16.04安装RabbitMQ(单机版)

    说明: 1.如果是做RabbitMQ方面的开发时,建议先不要了解集群的安装和部署,先安装一个单机版之后,尽快的熟悉里面的功能和特性.毕竟单机版支持的QPS相当的高.同样,集群方式也没有想象中的多点复制 ...

  9. NHibernate官方文档中文版--拦截器和事件(Interceptors and events)

    对于应用程序来说,能够对NHibernate内部发生的事件做出响应式很有用的.这能够有助于实现一些类的功能或者扩展NHibernate的功能. 拦截器 IInterceptor接口提供了应用程序ses ...

  10. linux安装配置redis

    redis是支持linux的,所以linux安装redis非常简单,按照官网的提示操作即可. 下载 $ wget http://download.redis.io/releases/redis-3.2 ...