二 Linux进程间通信( 二 )

代码示例:
#include<stdio.h>#include<signal.h>#include<sys/types.h>#include<unistd.h> int main() {int i = 1;while(1){printf("do working %d\n",i);//给自己发送一个信号if(i == 4){//自己给自己发送编号为15的信号raise(SIGTERM);}i ++;sleep(1);}return 0; }运行结果如下:

二 Linux进程间通信

文章插图
(3)abort函数
#include<stdlib.h>void abort(void);功能:给自己发送异常终止信号6)SIGABRT,并且产生core文件,等价于kill(getpid(),SIGABRT);参数:无返回值:无代码示例:
#include<stdio.h>#include<signal.h>#include<sys/types.h>#include<unistd.h> int main() {int i = 1;while(1){printf("do working %d\n",i);//给自己发送一个信号if(i == 4){//给自己发送一个编号为6的信号,默认的行为就是终止进程abort();}i ++;sleep(1);}return 0; }运行结果如下:
二 Linux进程间通信

文章插图
通过软件条件产生在上一篇博客介绍过,管道如果读端不读了 , 存储系统会发生SIGPIPE 信号给写端进程 , 终止进程 。这个信号就是由一种软件条件产生的,这里再介绍一种由软件条件产生的信号SIGALRM(时钟信号) 。
#include<unistd.h>unsigned int alarm(unsigned int seconds);功能:设置定时器(闹钟) 。在指定seconds后,内核会给当前进程发送14)SIGALRM信号,进程收到该信号,默认动作终止 。每个进程都有且只有唯一的一个定时器 。取消定时器alarm(0),返回旧闹钟余下秒数 。参数:seconds:指定的时间,以秒为单位返回值:返回0或剩余的秒数
  • 定时,与进程状态无关(自然定时)就绪、运行、挂起(阻塞 , 暂停)、终止、僵尸.......无论进程处于何种状态,alarm都计时 。
代码示例:
#include<stdio.h>#include<signal.h>#include<sys/types.h>#include<unistd.h> int main() {unsigned int ret = 0;//第一次设置闹钟5秒之后就超时 发送对应的信号ret = alarm(5);printf("上一次闹钟剩下的时间是%u\n",ret);sleep(2);//之前没有超时的闹钟被新的闹钟给覆盖ret = alarm(4);printf("上一次闹钟剩下的时间是%u\n",ret);printf("按下任意键继续...");getchar();return 0; }运行结果:
二 Linux进程间通信

文章插图
通过硬件异常产生硬件异常被硬件以某种方式被硬件检测到并通知内核,然后内核向当前进程发送适当的信号 。这里给大家介绍两个硬件异常:CPU产生异常 和 MMU产生异常
CPU产生异常 发生除零错误,CPU运行单元会产生异常,内核将这个异常解释为信号,最后OS发送SIGFPE信号给进程 。
代码示例:
#include <stdio.h>#include <unistd.h>#include <signal.h>#include <stdlib.h>int main(){// 由软件条件产生信号alarm函数和SIGPIPE// CPU运算单元产生异常 , 内核将这个异常处理为SIGFPE信号发送给进程int a = 10;int b = 0;printf("%d", a/b);return 0;}运行结果小伙伴们自己下去运行一下吧~这里就不截图了
MMU产生异常: 当进程访问非法地址时,mmu想通过页表映射来将虚拟转换为物理地址 , 此时发现页表中不存在该虚拟地址,此时会产生异常,然后OS将异常解释为SIGSEGV信号,然后发送给进程
#include <stdio.h>#include <unistd.h>#include <signal.h>#include <stdlib.h>int main(){// MMU硬件产生异常 , 内核将这个异常处理为SIGSEGV信号发送给进程signal(11, handler);int* p = NULL;printf("%d\n", *p);return 0;}signal函数实现信号的捕捉#include<signal.h>typedef void(*sighandler_t)(int);//它定义了一个类型sighandler_t,表示指向返回值为void型(参数为int型)的函数(的)指针sighandler_t signal(int signum , sighandler_t handler);功能:注册信号处理函数(不可用于SIGKILL、SIGSTOP信号),即确定收到信号后处理函数的入口地址 。此函数不会阻塞 。参数:signum:信号的编号 , 这里可以填数字编号,也可以填信号的宏义 。handler:取值有3种情况:SIG_IGN:忽略该信号SIG_DFL:执行系统默认动作信号处理函数名:自定义信号处理函数,如:func回调函数的定义如下:void func(int signo){//signo为触发的信号 , 为signal()第一个参数的值}返回值:成功:第一次返回NULL,下一次返回此信号上一次注册的信号处理函数的地址 。如果需要使用此返回值,必须在前面先声明此函数指针的类型 。失败:返回SIG_ERR

推荐阅读