Ric*_*ard 6 multithreading operating-system signal-handling
我有一个p
注册了信号处理程序的进程SIGALRM
.设置定时器以周期性地发送信号SIGALRM
进行处理p
.还有多个线程在运行p
.信号处理程序在被触发和执行时是否是不可抢占的?或者说,是否信号处理程序的执行不会被进程中的任何线程中断p
?
PS:我认为信号处理程序是在内核中执行的(是吗?)而内核对于用户模式线程是不受限制的?纠正我,如果它错了......
Lyk*_*yke 16
几乎 - 不要 - 在信号处理程序中处理共享数据几乎总会导致一个痛苦的世界,同时处理线程,你自己也搞得一团糟.
默认情况下,信号处理程序运行时会阻塞信号(至少在linux上,这可能不是普遍适用的),因此至少信号处理程序不会被自己抢占.但是,如果你有多个线程,并且信号没有在其他线程中被阻塞,那么信号处理程序很可能在几个线程内并发运行.
一个线程将接收信号并执行处理程序,它或多或少是随机的线程,尽管你可以通过阻止你不想处理信号的所有线程中的信号来控制它.
但是,处理信号的任何其他线程都可以并行运行.处理信号的线程可以在程序中的几乎任何点运行信号处理程序(只要信号没有被阻塞).因此,您需要某种锁定来保护该数据.问题是你不能使用任何普通的线程锁定原语,它们不是信号异步安全.这意味着如果您尝试在信号处理程序中获取pthread_mutex_t,则很容易使程序死锁.
您可以在信号处理程序中安全调用的唯一函数是此处列出的函数.关于保护共享数据,您可以使用sigblock()/ sigunblock()作为一种保护,确保在您访问共享数据时信号处理程序不会运行 - 并且信号必须在所有线程,否则它只会在其中一个没有被阻塞的线程中运行 - 走这条路是疯狂的.
几乎可以在信号处理程序中安全访问的唯一共享数据是一种sig_atomic_t
类型,实际上其他类型的原始类型通常也是安全的.
你在信号处理程序中真正应该做的只是
要么
要么
信号处理程序在被触发和执行时是否是不可抢占的?
不,信号处理程序像任何其他用户级功能一样是抢占式的.
我以为信号处理程序是在内核中执行的(是吗?)
不,信号处理程序不在内核模式下执行.
在从内核模式切换到用户模式时,内核检查进程的挂起信号.如果它找到待处理信号,则设置用户的堆栈帧,使得在返回用户模式之后,该过程开始执行信号处理程序.此后,进程在用户模式下开始执行,执行信号处理程序,就像任何其他用户级别函数一样.执行完成后,进程切换到内核模式.然后内核恢复进程的原始上下文,在信号处理之前执行.
所有这种模式切换都不是魔术.内核更改用户堆栈中的相应返回地址.
归档时间: |
|
查看次数: |
4341 次 |
最近记录: |