Linux编程基础之进程间通信之三:信号
来源:互联网 发布:阿里云os安全吗? 编辑:程序博客网 时间:2024/05/29 06:30
一、信号的概述
信号是UNIX 中所使用的进程通信的一种最古老的方法。。它是在软件层次上对中断机制的一种模拟,是一种异步通信方式。信号可以直接进行用户空间进程和内核进程之间的交互,内核进程也可以利用它来通知用户空间进程发生了哪些系统事件。它可以在任何时候发给某一进程,而无需知道该进程的状态。如果该进程当前并未处于执行态,则该信号就由内核保存起来,直到该进程恢复执行再传递给它为止;如果一个信号被进程设置为阻塞,则该信号的传递被延迟,直到其阻塞被取消时才被传递给进程。
一个完整的信号生命周期可以分为3 个重要阶段,这3 个阶段由4 个重要事件来刻画的:信号产生、信号在进程中注册、信号在进程中注销、执行信号处理函数,如下图所示:
用户进程对信号的响应有三种方式:
- 忽略信号,即对信号不做任何处理,但是有两个信号不能忽略,即SIGKILL 及SIGSTOP。
- 捕捉信号,定义信号处理函数,当信号发生时,执行相应的自定义处理函数。
- 执行缺省操作,Linux 对每种信号都规定了默认操作。
二、信号处理
信号处理的主要方法有两种,一种是使用简单的signal()函数,另一种是使用信号集函数组。下面分别介绍这两种处理方式。
1、使用signal()函数
使用signal()函数处理时,只需要指出要处理的信号和处理函数即可。它主要是用于前32 种非实时信号的处理,不支持信号传递信息,但是由于使用简单、易于理解,因此也受到很多程序员的欢迎。Linux 还支持一个更健壮、更新的信号处理函数sigaction(),推荐使用该函数。
函数格式:
void (*signal(int signum, void (*handler)(int)))(int)signum : 指定信号代码
handler:信号处理函数,可以是SIG_IGN、SIG_DFL、用户自定义
2、使用sigaction()函数
函数格式:
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact)signum :信号代码,可以为除SIGKILL 及SIGSTOP 外的任何一个特定有效的信号
act:指向结构sigaction 的一个实例的指针,指定对特定信号的处理
oldact:保存原来对相应信号的处理
返回值:0成功,其他返回错误代码
三、测试
分别对上述两种方式实现的信号处理进行测试。他们实现的功能都是一样的,编写一个信号处理函数用来捕捉用户输入的SIGINT信号(Ctrl + C)。
1、使用signal()函数
完整测试代码如下:
#include <stdio.h>#include <signal.h>#include <unistd.h>/* 自定义的信号处理函数 */void my_signal_func(int signum){if(signum == SIGINT){printf("Captured the signal is SIGINT!\n");}else{printf("Cptured error!\n");}}/* *功能 : 捕捉SIGINT信号 */int main(void){printf("Capture SIGINT signal!\n");/* 捕捉相应的信号 */signal(SIGINT, my_signal_func);/* wait a signal */pause();return 0;}编译并运行,结果如下:
2、使用sigaction()函数
完整的代码如下所示:
#include <stdio.h>#include <signal.h>#include <unistd.h>#if 0struct sigaction { void (*sa_handler)(int); void (*sa_sigaction)(int, siginfo_t *, void *); sigset_t sa_mask; int sa_flags; void (*sa_restorer)(void);};#endif/* 信号处理函数 */static void my_signal_func(int signum){if(signum == SIGINT){printf("Captured the signal SIGINT!\n");}else{printf("Captured error!\n");}}/* *功能 : 捕捉信号SIGINT */int main(void){int ret;struct sigaction my_sigaction;printf("Capture the siganl SIGINT!\n");/* 设置my_sigaction结构体 */my_sigaction.sa_handler = my_signal_func;sigemptyset(&my_sigaction.sa_mask);my_sigaction.sa_flags = 0;/* 将相应的信号与信号处理函数绑定起来 */ret = sigaction(SIGINT, &my_sigaction, 0);pause();// wait for signalreturn 0;}编译并运行结果如下所示:
- Linux编程基础之进程间通信之三:信号
- linux基础编程:进程通信之信号
- Linux进程间通信三之信号与处理
- Linux进程间通信(五)---信号通信之signal()、信号集函数组及其基础实验
- Linux进程间通信(五)---信号通信之signal()、信号集函数组及其基础实验
- Linux进程间通信之信号
- Linux进程间通信之信号
- linux进程间通信之信号
- linux进程间通信之信号
- Linux 进程间通信之信号
- linux之进程间通信--使用信号
- linux进程间通信之信号
- Linux进程间通信之信号
- linux 进程通信之信号
- linux进程通信之信号
- Linux进程通信之信号
- Linux进程通信之信号
- linux 进程通信之 信号
- 光源选型
- nginx配置介绍
- 文件操作需注意的地方
- 查找我的iphone怎么用详细教程
- 如何将svn与Android Studio关联和取消关联
- Linux编程基础之进程间通信之三:信号
- 京东举办首个中国品牌日,响应国家政策的同时怒怼阿里
- 练习2:简单的堆栈,队列,链表
- Java集合与数组的转换
- 通过索引或指针对数组元素进行访问
- 以梦喂马,驰骋岁月;以梦为马,诗酒趁年华。
- 珍重
- JNI简单实现demo
- Android Gradle文件下获取自定义properties文件,并且获取值或者修改值