Linux编程基础之进程间通信之三:信号

来源:互联网 发布:阿里云os安全吗? 编辑:程序博客网 时间:2024/05/29 06:30

一、信号的概述

信号是UNIX 中所使用的进程通信的一种最古老的方法。。它是在软件层次上对中断机制的一种模拟,是一种异步通信方式。信号可以直接进行用户空间进程和内核进程之间的交互,内核进程也可以利用它来通知用户空间进程发生了哪些系统事件。它可以在任何时候发给某一进程,而无需知道该进程的状态。如果该进程当前并未处于执行态,则该信号就由内核保存起来,直到该进程恢复执行再传递给它为止;如果一个信号被进程设置为阻塞,则该信号的传递被延迟,直到其阻塞被取消时才被传递给进程。

一个完整的信号生命周期可以分为3 个重要阶段,这3 个阶段由4 个重要事件来刻画的:信号产生、信号在进程中注册、信号在进程中注销、执行信号处理函数,如下图所示:


用户进程对信号的响应有三种方式:

  • 忽略信号,即对信号不做任何处理,但是有两个信号不能忽略,即SIGKILL 及SIGSTOP。
  • 捕捉信号,定义信号处理函数,当信号发生时,执行相应的自定义处理函数。
  • 执行缺省操作,Linux 对每种信号都规定了默认操作。
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;}
编译并运行结果如下所示:



0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 手机4g突然变2g怎么办 江湖风云录八卦门任务拒绝了怎么办 百度网盘下载时显示违规信息怎么办 在海马助手下载的游戏闪退怎么办 手机版百度云盘不能普通下载怎么办 手机版百度云盘一直加载中怎么办 登别人的网盘单同步通讯录了怎么办 被培训公司骗了贷款之后该怎么办 乐教乐学孩子登陆你那忘记了怎么办 脸擦破了痂掉了留斑怎么办 挤黑头后鼻子又红又疼怎么办 香奈儿邂逅清新淡香水不喷怎么办 脚面被压了肿起来了怎么办 每天加班很累反而失眠严重怎么办 减肥药吃了口臭嘴巴苦怎么办 上火引起的牙疼怎么办吃什么药 舌苔厚口气重怎么办应该吃什么药 宝宝老是额头热四肢不热怎么办 考老师考砸了心理崩溃了怎么办 苹果手机一会白屏一会黑屏怎么办 360云盘的东西删不了怎么办 手机邮箱打开的文件疑似病毒怎么办 电脑qq发送的文件失效了怎么办 小米4c温控文件打开是乱码怎么办 超星尔雅用学号登录密码忘了怎么办 全脸做激光去黄褐斑后脸发红怎么办 上传到微云中的视频下载不了怎么办 微云保存的小电影下载不了怎么办 苹果手机下载有云朵下载不了怎么办 手机下载登录忘了密码了怎么办 软软件被手机加密忘了密码怎么办 苹果手机想下载东西忘了密码怎么办 已经不念书几年了突然想上学怎么办 江湖风云录把王老爷子杀了怎么办 练扫踢胫骨旁边的肌肉受伤了怎么办 四个月宝宝没抱住摔了头部怎么办 老公老是跟年轻的小姑娘聊天怎么办 老婆出轨老公想离婚又舍不得怎么办 孕妇打完无痛分娩针就想睡觉怎么办 熟食店开空调菜品吹的很干怎么办 不锈钢锅在液化气烧了发黄怎么办