本文详细介绍了Linux中将信号处理同步化的技术,包括sigwait、sigwaitinfo、sigtimedwait和signalfd。信号作为异步事件,其处理方式包括忽略、捕捉和执行默认动作。在多线程环境中,信号处理是共享的,而sigwait等函数可以使信号处理变得同步,避免中断线程。sigwaitinfo和sigtimedwait提供了额外的信号信息和超时功能。signalfd则创建了一个接收信号的文件描述符,可用于select、poll和epoll。
摘要由CSDN通过智能技术生成
信号是典型的异步事件。内核在某个信号出现时有三种处理方式:
a:忽略信号,除了SIGKILL和SIGSTOP信号不能忽略外,其他大部分信号都可以被忽略;
b:捕捉信号,也就是在信号发生时调用一个用户函数,注意不能捕捉SIGKILL和SIGSTOP;
c:执行系统默认动作,注意大多数信号的系统默认动作是终止进程。
调用execve执行一个新的进程时,新进程的信号处理方式要么是忽略,要么是系统默认方式。如果调用进程忽略该信号,则新进程也忽略该信号,如果调用进程捕捉该信号,或者执行系统默认动作,新进程则按照默认行为处理该信号,这是因为调用进程的信号处理函数在新进程中已经无效了。
如果是调用fork产生子进程,则子进程的信号处理方式完全继承父进程的处理方式。这是因为子进程复制了父进程的地址空间,因此父进程中的信号处理函数在子进程中同样被复制了。
当信号产生以后,对信号采取了动作时,称为向进程“递送”了一个信号,在信号产生(generation)和递送(delivery)之间的时间间隔内,称信号是未决的(pending)。
进程可以“阻塞”信号,如果为进程产生了一个阻塞的信号,而且对该信号的动作是调用信号处理函数捕捉该信号,或者是系统默认动作,则会为该进程将此信号保持为未决状态,直到a:对此信号解除了阻塞,或者b:对此信号的动作改为忽略。内核在递送一个原来被阻塞的信号给进程时(而不是产生信号时),才决定对它的处理方式,因此,进程在信号被递送之前仍可改变对该信号的动作。
如果在进程解除某个信号的阻塞之前,该信号发生了多次,则系统可以递送该信号一次或多次。如果递送多次,则称对这些信号进行了排队。但是除非支持POSIX.1实时扩展,否则大多数UNIX并不对信号排队,也就是指递送该信号一次。
如果有多个信号要递送给一个进程,POSIX.1并未规定这些信号的递送顺序。
每个进程都有一个信号屏蔽字,它规定了当前要阻塞的信号集。POSIX.1使用数据类型sigset_t表示一个信号集,进程可以调用sigprocmask来检测和更改当前信号屏蔽字。
对信号的处理是以进程为单位的,也就是说在多线程环境中,信号的处理是进程中所有线程共享的。但是每个线程可以有自己的信号屏蔽字,所以,单个线程可以阻塞某些信号,当某个线程修改了某个信号的处理方式后,所有线程共享这个处理方式的改变。
进程中的信号是递送到单个线程的。如果信号与硬件故障相关,该信号就被递送到引起该事件的线程中去,而其他信号则被递送到任意一个没有阻塞该信号的线程。sigprocmask的行为在多线程中没有定义,线程必须使用相应的pthread_sigmask。
除了使用信号处理函数异步的捕捉信号之外,还可以将这种异步行为变得同步,有两种方法:
a:调用sigwaitinfo、sigtimedwait或sigwait,这些函数会阻塞调用线程,直到信号集set中的某个信号被递送为止,这些函数都会返回递送信号的信息。
b:调用signalfd,它返回一个文件描述符,针对该描述符的read的操作将会阻塞,直到signalfd指定的信号集set中的某个信号递送给调用者为止,此时read返回一个描述该信号的结构。
异步
信号
的同步处理——慢时钟域到快时钟域一、什么是亚稳态1.亚稳态发生原因2.亚稳态发生场合3.亚稳态危害二、理论
分析
1、
信号
传输中的亚稳态三、
异步
信号
的同步处理,慢时钟域到快时钟域1、程序2、适用条件
一、什么是亚稳态
1.亚稳态发生原因
在FPGA系统中,如果数据传输中不满足触发器的Tsu和Th不满足,或者复位过程中复位
信号
的释放相对于有效时钟沿的恢复时间(recovery
time
)不满足,...
1.
异步
信号
的同步处理——慢时钟域到快时钟域https://blog.csdn.net/qq_39485231/article/details/105381014
2.
异步
信号
的同步处理——快时钟域到慢时钟域(方法一)https://blog.csdn.net/qq_39485231/article/details/105378323
3.
异步
信号
的同步处理——快时钟域到慢时钟域(方法二) https://blog.csdn.net/qq_39485231/article/details/105380869
AS DIGITAL DE
SIG
N BECOMES INCREASINGLY SOPHISTICATED,CIRCUITS WITH MULTIPLE CLOCKS MUST RELIABLY COMMUNICATE WITH EACH OTHER.
Crossing the abyss:
asynchronous
signal
s
in a synchronous world
Libev
中的
信号
监视器,用于监控
信号
的发生,因
信号
是
异步
的,所以
Libev
的处理方式是尽量的将
异步
信号
同步化
。
异步
信号
的
同步化
方法主要有:
signal
fd
、event
fd
、pipe、
sig
wait
info
等。这里
Libev
采用的是前三种方法,最终都是将对
异步
信号
的处理,转化成对文件描述符的处理,也就是将ev_
signal
转化为处理ev_io。
一:数据结构
1:ev_
signal
异步
信号
的
同步化
异步
信号
同步化
的目的就是在于消除可能存在的亚稳态至于什么是
异步
信号
同步化
,请自行google…这里直接通过两级寄存器对
异步
信号
处理实现
同步化
reg rx_1,rx_2;
always@(posedge clk or negedge rst_n)
if(!rst_n)begin
rx_1 <= 1'b0;
rx_2 <= 1'b0
该图显示了当在一个时钟域中生成的
信号
被采样得太接近来自另一个时钟域的时钟
信号
的上升沿时发生的同步故障。 同步失败是由输出变为亚稳态引起的,并且在输出必须再次采样时不会收敛到合法稳定状态。
在《
libev
源码
解析——总览》一文中,我们介绍过,
libev
是一个基于事件的循环库。本文将介绍其和事件及循环之间的关系。(转载请指明出于breaksoftware的csdn博客)
目前ibev支持如下IO事件模型:
select模型。对应文件是ev_select.c。
poll模型。对应文件是ev_poll.c。
epoll模型。对应的文件是ev_epol...
1 线程的基本概念
Linux下的线程在内核是作为共享存储区、共享文件系统、共享
信号
处理、共享文件描述符,拥有独立进程表项的独立进程看待的,而线程的创建、同步、删除等操作都在核外进行。
编写Linux下的线程程序,需要包含头文件,链接时需要使用库libpthread.a。
2 线程的使用
2.1 线程的创建
intpthread_create( pthrea
1.
sig
wait
函数:
sig
wait
等一个或者多个指定
信号
发生。
它所做的工作只有两个:第一,监听被阻塞的
信号
;第二,如果所监听的
信号
产生了,则将其从未决队列中移出来(这里实时
信号
和非实时
信号
又有区别,体现在取出的顺序等,具体自己取网上查,这里不再详述)。
sig
wait
并不改变
信号
掩码的阻塞与非阻塞状态。
在POSIX标准中,当进程收到
信号
时,如果是多线程的情况,我们是
Linux 多线程环境中的
信号
处理不同于进程的
信号
处理。一方面线程间
信号
处理函数的共享性使得
信号
处理更为复杂,另一方面普通
异步
信号
又可转换为同步方式来简化处理。
本文首先介绍
信号
处理在进程中和线程间的不同,然后描述相应的线程库函数,在此基础上给出一组示例代码,以讨论线程编程中
信号
处理的细节和注意事项。
本文通过
sig
wait
() 调用来“等待”
信号
,而通过
signal
()/
sig
ac