在Linux中,要发送一个信号相当容易。程序员需要知道两个信息:要发送哪个信号,将这个信号发送给哪个进程。可以用 man 7 signal 找到一个可以利用的信号的列表。用户可以只将信号发送给用户自己的进程,也可以以root身份运行从而将信号发送给任意一进程。

Source:

#include<stdio.h> #include<signal.h> #include<unistd.h> #include<stdlib.h> void when_alarm(); void when_sigint(); void when_sigchld(int); void when_sigusr1(); void when_sigio(); int main() { int childpid;//子程序进程ID号 printf("程序已经开始运行,5秒钟后将接收到时钟信号。/n"); if ((childpid=fork())>0)//父进程 { signal(SIGALRM,when_alarm); //当接收到SIGALRM信号时,调用when_alarm函数 signal(SIGINT,when_sigint); //当接收到SIGINT信号时,调用when_sigint函数 signal(SIGCHLD,when_sigchld);//当接收到SIGCHLD信号时,调用when_sigchld函数 signal(SIGUSR1,when_sigusr1);//当接收到SIGUSR1信号时,调用when_sigusr1函数 signal(SIGIO,when_sigio);//当接收到SIGIO信号时,调用when_sigio函数 alarm(5); //5秒钟之后产生SIGALRM信号 raise(SIGIO); //向自己发送一个SIGIO信号 pause(); //将父进程暂停下来,等待SIGALRM信号到来 pause(); //将父进程暂停下来,等待SIGUSR1信号到来 pause(); //将父进程暂停下来,等待SIGCHLD信号到来 printf("------此时程序会停下来等待,请按下ctrl+c送出SIGINT信号-------/n"); pause(); //将父进程暂停下来,等待SIGINT信号到来 } else if(childpid==0) //子进程 { int timer; for(timer=7;timer>=0;timer--) //时钟计时5秒产生SIGALRM信号,再过2秒子进程退出,产生SIGCHLD信号 { if(timer>2) printf("距离SIGALRM信号到来还有%d秒。/n",timer-2); if(timer==4) kill(getppid(),SIGUSR1); //向父进程发送一个SIGUSR1信号 if((timer<=2)&&(timer>0)) printf("子进程还剩%d秒退出,届时会产生SIGCHLD信号。/n",timer); if(timer==0) //子进程退出,产生SIGCHLD信号 raise(SIGKILL); //子进程给自己发一个结束信号 sleep(1); //每个循环延时1秒钟 } } else printf("fork()函数调用出现错误!/n"); return 0; } void when_alarm() { printf("5秒钟时间已到,系统接收到了SIGALRM信号!/n"); } void when_sigint() { printf("已经接收到了SIGINT信号,程序将退出!/n"); exit(0); } void when_sigchld(int SIGCHLD_num) { printf("收到SIGCHLD信号,表明我的子进程已经中止,SIGCHLD信号的数值是:%d。/n",SIGCHLD_num); } void when_sigusr1() { printf("系统接收到了用户自定义信号SIGUSR1。/n"); } void when_sigio() { printf("系统接收到了SIGIO信号。/n"); }

Result:

[work@db-testing-com06-vm3.db01.baidu.com c++]$ ./signal_test

程序已经开始运行,5秒钟后将接收到时钟信号。

距离SIGALRM信号到来还有5秒。

系统接收到了SIGIO信号。

距离SIGALRM信号到来还有4秒。

距离SIGALRM信号到来还有3秒。

距离SIGALRM信号到来还有2秒。

系统接收到了用户自定义信号SIGUSR1。

距离SIGALRM信号到来还有1秒。

5秒钟时间已到,系统接收到了SIGALRM信号!

子进程还剩2秒退出,届时会产生SIGCHLD信号。

子进程还剩1秒退出,届时会产生SIGCHLD信号。

收到SIGCHLD信号,表明我的子进程已经中止,SIGCHLD信号的数值是:17。

------此时程序会停下来等待,请按下ctrl+c送出SIGINT信号-------

已经接收到了SIGINT信号,程序将退出!

信号参考对照表:

Signal

Description

SIGABRT

由调用abort函数产生,进程非正常退出

SIGALRM

用alarm函数设置的timer超时或setitimer函数设置的interval timer超时

SIGBUS

某种特定的硬件异常,通常由内存访问引起

SIGCANCEL

由Solaris Thread Library内部使用,通常不会使用

SIGCHLD

进程Terminate或Stop的时候,SIGCHLD会发送给它的父进程。缺省情况下该Signal会被忽略

SIGCONT

当被stop的进程恢复运行的时候,自动发送

SIGEMT

和实现相关的硬件异常

SIGFPE

数学相关的异常,如被0除,浮点溢出,等等

SIGFREEZE

Solaris专用,Hiberate或者Suspended时候发送

SIGHUP

发送给具有Terminal的Controlling Process,当terminal被disconnect时候发送

SIGILL

非法指令异常

SIGINFO

BSD signal。由Status Key产生,通常是CTRL+T。发送给所有Foreground Group的进程

SIGINT

由Interrupt Key产生,通常是CTRL+C或者DELETE。发送给所有ForeGround Group的进程

SIGIO

异步IO事件

SIGIOT

实现相关的硬件异常,一般对应SIGABRT

SIGKILL

无法处理和忽略。中止某个进程

SIGLWP

由Solaris Thread Libray内部使用

SIGPIPE

在reader中止之后写Pipe的时候发送

SIGPOLL

当某个事件发送给Pollable Device的时候发送

SIGPROF

Setitimer指定的Profiling Interval Timer所产生

SIGPWR

和系统相关。和UPS相关。

SIGQUIT

输入Quit Key的时候(CTRL+/)发送给所有Foreground Group的进程

SIGSEGV

非法内存访问

SIGSTKFLT

Linux专用,数学协处理器的栈异常

SIGSTOP

中止进程。无法处理和忽略。

SIGSYS

非法系统调用

SIGTERM

请求中止进程,kill命令缺省发送

SIGTHAW

Solaris专用,从Suspend恢复时候发送

SIGTRAP

实现相关的硬件异常。一般是调试异常

SIGTSTP

Suspend Key,一般是Ctrl+Z。发送给所有Foreground Group的进程

SIGTTIN

当Background Group的进程尝试读取Terminal的时候发送

SIGTTOU

当Background Group的进程尝试写Terminal的时候发送

SIGURG

当out-of-band data接收的时候可能发送

SIGUSR1

用户自定义signal 1

SIGUSR2

用户自定义signal 2

SIGVTALRM

setitimer函数设置的Virtual Interval Timer超时的时候

SIGWAITING

Solaris Thread Library内部实现专用

SIGWINCH

当Terminal的窗口大小改变的时候,发送给Foreground Group的所有进程

SIGXCPU

当CPU时间限制超时的时候

SIGXFSZ

进程超过文件大小限制

SIGXRES

Solaris专用,进程超过资源限制的时候发送

==========================================================================

signal学习推荐:


信号(signal)介绍(Linux中国)

http://www.linux-cn.com/html/linux/system/20070505/27605.shtml

Linux 信号signal处理函数(CSDN)

http://blog.csdn.net/Sunboy_2050/archive/2010/10/16/5945535.aspx

Linux 信号signal处理机制(CSDN)

http://blog.csdn.net/Sunboy_2050/archive/2010/10/16/5945380.aspx

==========================================================================
         程序员可以调用 int raise(int signo) 将一个信号发送给它自己。这个函数只带有一个参数,既要发送信号的编号。如:raise(SIGINT); raise(SIGKILL);
         让人感兴趣的是函数 unsigned int alarm(unsigned int seconds) 它可以让用户进程在将来某个指定的时间接收到一个信号。alarm()的唯一参数是将来信号SIGALRM应该在多少秒以后发送给用户进程。当用户调用alarm()时,前面任何一个请求的报警信号(不包括悬挂起来被阻塞的SIGALRM信号)都将被取消,调用的返回值是前面请求的剩余时间。alarm()范例如下:
    
if(signal(SIGALRM,alarmhandler)==SIG_ERR)
{
     printf("Couldn't register signal handler./n"); 
}
alarm(5);      // 5秒钟以后,程序将会收到一个SIGALRM信号
for(i=0;i<10;i++)
{
     sleep(3);
}
void alarmhandler(int signum)
{
     printf("alarmhandler./n"); 
}

也可以使用 int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue) 来实现更精确更方便的定时控制。
         参数which一般取ITIMER_REAL,它使得用户的计时器根据系统时钟来计算时间。当计数时间到期时,它将发送一个SIGALRM信号。其功能和alarm()一样,所以用户不能将两者同时使用。
         结构itimerval的定义如下:
struct itimerval 

     struct timeval it_interval; // 每一次触发报警后应该被复位的值,为0报警被禁止
     struct timeval it_value;     // 下一次触发报警的时间,为0报警将只触发一次
};
         结构timeval的定义如下:
strut timeval

     long tv_sec;       // 秒数 
     long tv_usec;     // 微秒数
};
         setitimer()范例如下:

struct itimerval itimer;
itimer.it_interval.tv_usec = 0;     // it_interval字段指定了每一次触发后应该被复位的值
itimer.it_interval.tv_sec     = 2;

itimer.it_value.tv_usec = 0;        // it_value字段指定了直到下一次触发的时间   
itimer.it_value.tv_sec     = 5;
setitimer(ITIMER_REAL,&itimer,NULL);

for(i=0;i<10;i++)
{
     sleep(3);
}

void alarmhandler(int signum)
{
     printf("alarmhandler./n"); 
}

Linux下的signal信号机制相关推荐

  1. 组合键 发送指定信号_Django signal 信号机制的使用

    Django中提供了"信号调度",用于在框架执行操作时解耦,当某些动作发生的时候,系统会根据信号定义的函数执行相应的操作 一.Django中内置的 signal 类型主要包含以下几 ...

  2. linux 信号优先级,linux内核中的信号机制

    linux内核中的信号机制--信号处理 Kernel version:2.6.14 CPU architecture:ARM920T Author:ce123(http://blog.csdn.net ...

  3. 从一道面试题谈linux下fork的运行机制

    http://kb.cnblogs.com/page/76622/ 今天一位朋友去一个不错的外企面试linux开发职位,面试官出了一个如下的题目: 给出如下C程序,在linux下使用gcc编译: #i ...

  4. Linux下程序的保护机制(checksec)

    Linux下程序的保护机制 前言 相信很多人,查看程序信息时会用到,checksec这个命令.它会给你返回如下图的结果,但是很多最开始看到的人,很多都看不懂,如果身为小白的我,跟在大佬后面比葫芦画瓢, ...

  5. 机制 linux_从一道面试题谈linux下fork的运行机制

    今天一位朋友去一个不错的外企面试linux开发职位,面试官出了一个如下的题目: 给出如下C程序,在linux下使用gcc编译: #include "stdio.h" #includ ...

  6. LINUX下FORK的运行机制详细解析

    摘要:由于fork函数运行机制的复杂性,造就了当两个fork并排时,问题就变得很复杂.解这个题的关键,一是要对linux下进程的机制有一定认识,二是抓住上文提到的几个关于fork的关键点. 今天一位朋 ...

  7. linux下 如何用信号signal 终止或者暂停子线程,linux下实现线程暂停

    记得在windows下有一个SuspendThread使线程挂起的函数,却发现linux下没有类似的函数,于是想自己写个.. 刚开始就想到用信号(没办法,正在看auep,只能想到这个) test1: ...

  8. Linux下进程间通信的六种机制详解

    linux下进程间通信的几种主要手段:        1.管道(Pipe)及有名管道(named pipe):管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具 ...

  9. linux通过信号回调函数,信号机制的管理结构 - Linux内核中的信号机制_Linux编程_Linux公社-Linux系统门户网站...

    信号只是一个数字,数字为0-31表示不同的信号,如下表所示. 编号 信号名 默认动作 说明 1 SIGHUP 进程终止 终端断开连接 2 SIGINT 进程终止 用户在键盘上按下CTRL+C 3 SI ...

最新文章

  1. 未来已来:全球XR产业洞察
  2. Artificial Intelligence Yourself
  3. win10 自定义分辨率
  4. 【Java】 5.6 类的继承
  5. 计算机硬件性能提升定律,❤️多核编程·笔记
  6. Linux学习笔记:安装python
  7. Blazor 版 Bootstrap Admin 通用后台权限管理框架
  8. 利用cors,实现js跨域访问Tomcat下资源
  9. 【Flink】Flink 清理过期 Checkpoint 目录的正确姿势
  10. 逾期怎么处理_信用卡3万逾期三个月,催收说已经起诉生效,立案处理了,该怎么办?...
  11. 20款优秀的可以替代桌面软件的Web应用(转载自JavaEye)
  12. 计算机网络安全 单词
  13. win7自带tftp服务器,如何打开tftp服务器,笔者教你Win7系统TFTP服务器怎么开启
  14. HTML 命名规范说明
  15. Java-微信公众号-上(环境搭建+基础回复功能)
  16. 打飞机小游戏c++窗口实现版
  17. [渝粤教育] 西南科技大学 英语(A)1 在线考试复习资料
  18. 思维导图 基础篇(11)应用-文章分析-框架法
  19. 中国站立桨板桨市场趋势报告、技术动态创新及市场预测
  20. 2021数学建模国赛总结(含题目)

热门文章

  1. PyCharm和git安装教程
  2. windows 下 安装mysql 出现 “ ERROR 1045 (28000): Access denied for user ‘root’@‘localhost’ (using password
  3. electron 5.0.3版本 改动的地方
  4. 设计模式---4(抽象工厂模式的概念,产品组和产品等级的概念,抽象工厂模式的实现)
  5. 几种并发服务器模型的实现:多线程,多进程,select,poll,epoll
  6. 3-V2-类和对象 -- const内联 静态成员 友元
  7. Linux进程通信之mmap
  8. 不愧是阿里大佬,mysql存储过程写法案例
  9. Java 多线程 笔记 转自http://www.cnblogs.com/lwbqqyumidi/p/3804883.html
  10. SPRING IN ACTION 第4版笔记-第二章-002-@ComponentScan、@Autowired的用法