sigaction

Linux信号(signal) 机制分析

一个人想着一个人 提交于 2019-11-28 13:02:24
from: https://www.cnblogs.com/subo_peng/p/5325326.html 【摘要】本文分析了Linux内核对于信号的实现机制和应用层 的相关处理。首先介绍了软中断信号的本质及信号的两种不同分类方法尤其是不可靠信号的原理。接着分析了内核对于信号的处理流程包括信号的触发/注册/执行 及注销等。最后介绍了应用层的相关处理,主要包括信号处理函数的安装、信号的发送、屏蔽阻塞等,最后给了几个简单的应用实例。 【关键字】软中断信号,signal,sigaction,kill,sigqueue,settimer,sigmask,sigprocmask,sigset_t 1 信号本质 软中断信号(signal,又简称为信号)用来通知进程发生了异步事件。在软件层次上是对中断机制的一种模拟,在原理上,一个进程收到一个信号与处理器收到一个中断请求可以说是一样的。信号是进程间通信机制中唯一的异步通信机制,一个进程不必通过任何操作来等待信号的到达,事实上,进程也不知道信号到底什么时候到达。进程之间可以互相通过系统调用kill发送软中断信号。内核也可以因为内部事件而给进程发送信号,通知进程发生了某个事件。信号机制除了基本通知功能外,还可以传递附加信息。 收到信号的进程对各种信号有不同的处理方法。处理方法可以分为三类: 第一种是类似中断的处理程序,对于需要处理的信号

Why only async-safe functions should be called from a signal handler?

十年热恋 提交于 2019-11-28 10:48:51
问题 I understand that, from a signal handler function sigaction() I should only call those functions that are "async-safe". But why is so? 回答1: Calling an unsafe function may lead to undefined behavior. The Open Group Base Specifications Issue 7 (POSIX.1-2008), in its treatment of "Signal Concepts", says: [W]hen a signal interrupts an unsafe function ... and the signal-catching function calls an unsafe function, the behavior is undefined. As to why unsafe functions are unsafe, there may be many

sigaction()函数

时光毁灭记忆、已成空白 提交于 2019-11-26 22:27:42
sigaction函数 修改信号处理动作(通常在Linux用其来注册一个信号的捕捉函数) int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact); 成功:0;失败:-1,设置errno 参数: act:传入参数,新的处理方式。 oldact:传出参数,旧的处理方式。 【signal.c】 struct sigaction结构体 struct sigaction { void (*sa_handler)(int); void (*sa_sigaction)(int, siginfo_t *, void *); sigset_t sa_mask; int sa_flags; void (*sa_restorer)(void); }; sa_restorer:该元素是过时的,不应该使用,POSIX.1标准将不指定该元素。(弃用) sa_sigaction:当sa_flags被指定为SA_SIGINFO标志时,使用该信号处理程序。(很少使用) 重点掌握: ① sa_handler:指定信号捕捉后的处理函数名(即注册函数)。也可赋值为SIG_IGN表忽略 或 SIG_DFL表执行默认动作 ② sa_mask: 调用信号处理函数时,所要屏蔽的信号集合(信号屏蔽字)。注意

linux进程通信

廉价感情. 提交于 2019-11-26 20:10:00
linux常用进程通信方式包括管道(pipe)、有名管道(FIFO)、信号(signal)、消息队列、共享内存、信号量、套接字(socket)。 管道 管道是单向、先进先出的无结构的字节流。用于父子进程之间的通信。关键系统调用如下: int pipe( int fd[2] );fd数组用于返回两个fd,分别表示通道的两端。 int main(){ int pid; int fd[2]; if(pipe(fd)<0){//父进程创建管道 perror("Fail to pipe"); exit(EXIT_FAILURE); } if((pid=fork())<0){ perror("Fail to fork"); exit(EXIT_FAILURE); }else if(pid == 0){ close(fd[1]);//表示管道的方向,fd[1]用于写 child_read_pipe(fd[0]);//子进程读取管道 }else{ close(fd[0]);//fd[0]用于读 father_write_pipe(fd[1]);//父进程写入管道 } } 有名管道 有名管道以设备文件的形式存在,可被任意知道名字的进程使用,而不止在只有亲缘关系的进程之间。 要使用有名管道,必须先建立它,并与他的一段相连,才能打开进行读写。当文件不再需要时,要显示删除。系统调用: int mknod(