一 信号概念

在计算机科学中,信号(英语:Signals)是 Unix、类 Unix 以及其他 POSIX 兼容的操作系统中进程间通讯的一种有限制的方式。它是一种异步的通知机制,用来提醒进程一个事件已经发生。当一个信号发送给一个进程,操作系统中断了进程 正常的控制流程,此时,任何非原子操作都将被中断。如果进程定义了信号的处理函数,那么它将被执行,否则就执行默认的处理函数。
每个信号都有一个名字, 这些名字都以三个字符 SIG 开头。 例如,SIGABRT 是夭折信号, 当进程调用abort 函数时产生这种信号。SIGALRM 是闹钟信号,当由 alarm 函数设置的计时器超时后产生此信号。在UNIX 系统中,这些信号都定义在头文件 <signal.h> 中,并且都是以一个正整数来表示(信号编号)。通过在shell 中运行命令 kill -l 可以查看当前系统所执行的所有信号。
UNIX 系统规定了内核可以对信号执行以下三种处理行为,

  1. 忽略此信号。有两个信号 SIGKILL 和 SIGSTOP 不可忽略,这两个信号提供给超级用户终止或停止
    进程的可靠方法。
  2. 执行系统默认动作。大多数信号的默认动作是终止进程。
  3. 捕获信号,执行用户自定义的处理函数。
二 信号处理
2.1 signal 定义
       #include <signal.h>void (*signal(int num, void (*handler)(int))) (int)typedef void (*sighandler_t)(int);sighandler_t signal(int signum, sighandler_t handler);
2.2 signal的简单应用:
#include <signal.h>
#include <stdio.h>/*
*   void (*signal(int num, void (*handler)(int))) (int)
*   typedef void(handler_t)(int)
*   handler_t signal(int, handler_t)
*/void handler(int num)
{printf("handler: num = %d\n", num);
}int main(int argc, char const *argv[])
{//capture signal and binding signal handle functionsignal(SIGINT, handler);while (1);return 0;
}

Ubuntu下测试输出:

xxx@ubuntu:~/Documents/linux环境高级编程/signal$ ./a.out
^Chandler: num = 2
^Chandler: num = 2
^Chandler: num = 2
^\退出
2.3 raise and kill

UNIX 系统提供了两个函数 kill 和 raise 来产生信号。kill 函数将信号发送给指定的进程或进程组。
raise 函数则允许进程向自身发送信号。
#include <signal.h>

int kill(pid_t pid, int signo);
pid : 需要发送信号的进程的进程号
signo : 信号值

int raise(int signo); 给自己发送信号 等价于 kill(getpid(),signo);

#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <unistd.h>void handler(int num)
{printf("raise a signal!\n");
}int main(int argc, char const *argv[])
{//ignore SIGINT     signal//signal(SIGINT, SIG_IGN);//default//signal(SIGINT,SIG_DFL);signal(SIGINT, handler);sleep (3);raise(SIGINT);    //3秒后给自己发送一个SIGINT信号 Default action is to terminate the process. 终止进程return 0;
}

Ubuntu下测试输出:

xxx@ubuntu:~/Documents/linux环境高级编程/signal$ ./a.out
raise a signal!   //等待三秒之后的输出
2.4 signal在父子进程中使用

signal提供关于用于自定义的信号值如下:
SIGUSR1 30,10,16 Term User-defined signal 1
SIGUSR2 31,12,17 Term User-defined signal 2
关于signal更多信息使用 man 7 signal 命令查看

使用signal在父子进程中使用代码如下所示:

#include <signal.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>//wait : will chock and always ask.
//SIGHOLD: is similar to interrupt.void my_handler(int num)
{printf("the subprocess has ended!%d\n",num);printf("ID- %d, this is my_handler : num = %d\n", getpid(),num);int status;pid_t pid = wait(&status);// xxxxxx  See (man wait) for further specification for the status resolution
}void my_siguser1(int num)
{printf("ID- %d, this is my_siguser1 : num = %d\n", getpid(),num);
}int main(int argc, char const *argv[])
{pid_t pid = fork();if (pid < 0){perror("fork");return 0;}if (pid > 0){  // parent processprintf("parent process : pid = %d, ppid = %d\n", getpid(), getppid());sleep(1);signal(SIGCHLD,my_handler); kill(pid, SIGUSR1);while(1);}if (0 == pid){  //subprocessprintf("subprocess : pif = %d, ppid = %d\n", getpid(),getppid());//Both SIGUSR1 and SIGUSR2 are for user definesignal(SIGUSR1, my_siguser1);   //make SIGUSR1 bind my_siguser1 fuctionsleep(3);printf("the subprocess will end\n");//SIGCHLD before the subprocess end, it will send a SIGCHLD signal to parent process}return 0;
}

Ubuntu下测试输出:

xxx@ubuntu:~/Documents/linux环境高级编程/signal$ ./a.out
father process : pid = 3395, ppid = 2845
subprocess : pif = 3396, ppid = 3395
ID- 3396, this is my_siguser1 : num = 10
the subprocess end
the subprocess has ended!17
ID- 3395, this is my_handler : num = 17
^C
2.5 signal在父子进程中应用

使用fork创建两个子进程,父进接收stdin的输入,如果输入中含有“terminate_all”,则终止所有进程(包括父进程),否则,如果输入中含有“terminate_01”,则终止第一个子进程,否则,如果输入中含有“terminate_02”,则终止第二个子进程。
具体代码实现如下:

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <stdlib.h>int main(int argc, char const *argv[])
{pid_t pid1 = fork();if (pid1 < 0){perror("fork1");return -1;}else if (pid1 > 0){ pid_t pid2 = fork();if (pid2 < 0){perror("fork2");return -1;}else if (pid2 > 0){ //parent processchar * ch = (char *)malloc(100);while (1){scanf("%s", ch);if (strstr(ch, "terminate_all")){kill(pid1,SIGINT);kill(pid2,SIGINT);raise(SIGINT);}else if (strstr(ch, "terminate_01")){kill(pid1,SIGINT);}else if(strstr(ch, "terminate_02")){kill(pid2,SIGINT);}}}else if(0 == pid2){ // subprocess2 while (1){sleep(5);printf ("this is subprocess2\n");}}}else if(0 == pid1){ // subprocess1 while (1){sleep(5);printf ("this is subprocess1\n");}}return 0;
}

Ubuntu下测试输出:

xxx@ubuntu:~/Documents/linux环境高级编程/signal$ ./a.out
this is subprocess2
this is subprocess1
terminate_01
this is subprocess2
this is subprocess2
terminate_02
terminate_allxxx@ubuntu:~/Documents/linux环境高级编程/signal$ 

About signal in linux environment相关推荐

  1. A Linux Environment Zero Overhead

    本文翻译自Tilera公司关于ZOL机制的白皮书报告,原文为<Tilera_ZOL_White_Paper_0>,原文可以到这里下载http://download.csdn.net/det ...

  2. linux signal用法,Linux 信号 signal 用法详解及注意事项

    Linux 信号 signal 用法详解及注意事项 1) SIGHUP 本信号在用户终端连接 (正常或非正常) 结束时发出, 通常是在终端的控 制进程结束时, 通知同一 session 内的各个作业, ...

  3. linux. signal信号,Linux下signal信号汇总

    SIGHUP /* Hangup (POSIX). */ 终止进程 终端线路挂断 SIGINT /* Interrupt (ANSI). */ 终止进程 中断进程 Ctrl+C SIGQUIT /* ...

  4. signal 11 linux,signal 11 (SIGSEGV)错误排查

    jni调试最蛋疼的就是signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x4这种错误,爆出来完全不知道是哪句代码造成的,很难定位到问题所在, ...

  5. signal 11 linux,关于运行时Signal 11 Caught的错误

    我的程序在ubuntu7.10下运行的时候,有时候会出现如下的问题,但不是每次都出现,请问有编程经验的大牛能否指点一二,谢谢了 P2SP-SVCHOST: Signal 11 Caught. P2SP ...

  6. signal 11 linux,signal 11 定位

    关于关于signal 11段错误,如何快速定位 使用valgrind工具 1.下载最新代码http://valgrind.org/downloads/current.html: 2.解压tar xvf ...

  7. Linux Signal及Golang中的信号处理

    转载地址:https://colobu.com/2015/10/09/Linux-Signals/ 信号(Signal)是Linux, 类Unix和其它POSIX兼容的操作系统中用来进程间通讯的一种方 ...

  8. Linux signal()

    Linux signal() 转载请注明作者和原文出处,原文地址:https://blog.csdn.net/sym_07/article/details/87940232 1. 概念 信号(sign ...

  9. Linux信号sigaction / signal

    Linux信号sigaction / signal 文章目录 Linux信号sigaction / signal 目的 函数原型 struct sigaction 信号枚举值 ISO C99 sign ...

最新文章

  1. 聊一聊多源最短路径问题(只有5行代码哦)
  2. shell的相关知识(变量、脚本定义)
  3. 《统一沟通-微软-实战》-6-部署-2-中介服务器-1-定义中介服务器
  4. python软件是干什么用的-python中的django是做什么的
  5. Loading class `com.mysql.jdbc.Driver'. This is deprecated警告处理
  6. Apache伪静态学习
  7. JDK安装及java环境配置_JDK安装及Java环境变量配置
  8. 论文: YOLO9000-Better,Faster,Stronger
  9. centos7 如何安装部署k8s_如何在centos7上安装FreeIPA的客户端
  10. R中与数据挖掘相关的package
  11. java遍历键值对_map集合中的键值对对象遍历
  12. php spider 参数详解,利用phpspider爬取网站数据
  13. DM运维踩坑实践总结
  14. oracle 同义词转换错误,一次对dual表的恢复操作(ORA-00980:同义词转换不再有效错误解决方法) (转载)...
  15. RK3399 修改android桌面图标默认大小
  16. Wiki开源软件介绍
  17. PyQt5渐变圆环水波进度条+透明淡入(多线程信号)
  18. 手机快速将语音转换成文字的方法!详细步骤教你使用,方便又高效
  19. 为什么用IP查询网查询的自己的外网IP和用tracert命令查询的自己的出口IP不一致?
  20. 苹果呼叫转移设置不了_怎么设置别人电话打不进来

热门文章

  1. 模拟地下城与勇士(DNF)的装备强化过程
  2. 用Python制作七夕表白神器,让你成功概率提高99.9%
  3. “数字避孕”这事,我们可以信几分?
  4. 顿悟!新手都能学懂的SpringBoot源码分析!
  5. 什么是均方误差损失函数
  6. 16S的细菌群落功能预测工具PICRUSt2学习
  7. ggplot之绘制散点图
  8. 百万英雄、芝士超人、百万赢家、冲顶大会作弊神器
  9. <Principles of fMRI 1>课程笔记7 K空间
  10. 硬件电路开发中的电容常用知识