gpt4 book ai didi

multithreading - 在 linux 中信号处理程序的执行是不可抢占的吗?

转载 作者:行者123 更新时间:2023-12-04 06:49:01 26 4
gpt4 key购买 nike

我有一个进程pSIGALRM 的信号处理程序注册.设置定时器以定期发送信号 SIGALRM处理 p .进程中还有多个线程在运行 p .信号处理程序在被触发和执行时是否不可抢占?或者说,是不是信号处理程序的执行不会被进程中的任何线程中断p ?

PS:我认为信号处理程序是在内核中执行的(是吗?)并且内核对用户模式线程是不可抢占的?如果错了请纠正我...

最佳答案

几乎 - 不要 - 在信号处理程序中处理共享数据几乎总是会导致一个痛苦的世界,处理线程也是如此,并且您将自己弄得一团糟。

默认情况下,信号处理程序在运行时会阻塞信号(至少在 linux 上,这可能并非普遍适用),因此至少信号处理程序不会被自身抢占。但是,如果您有多个线程,并且信号没有在其他线程中阻塞,那么信号处理程序很可能会在多个线程中同时运行。

一个线程将接收信号并执行处理程序,它或多或少是随机的,尽管您可以通过在不想处理信号的所有线程中阻塞信号来控制它。

但是,任何其他线程都会阻止处理信号的线程可能并行运行。处理信号的线程几乎可以在程序中的任何一点运行信号处理程序(只要信号未被阻塞)。因此,您需要某种锁定来保护该数据。问题是你不能使用任何普通的线程锁定原语,它们不是信号异步安全的。意思是如果你例如尝试在信号处理程序中获取 pthread_mutex_t ,你很容易死锁你的程序。

您可以在信号处理程序中安全调用的唯一函数是列出的函数 here .
关于保护共享数据,您可以使用 sigblock()/sigunblock() 作为一种保护,确保在您访问共享数据时信号处理程序不会运行 - 并且信号必须在所有线程,否则它只会在没有阻塞的线程之一中运行 - 沿着这条路走下去是疯狂的。

几乎可以在信号处理程序中安全访问的唯一共享数据是 sig_atomic_t类型,实际上其他类型的原始类型通常也是安全的。

在信号处理程序中你真正应该做的只是

  • 设置全局标志
  • 在合适的时候检查代码中其他地方的标志,并采取行动

  • 或者
  • 有某种主循环使用 select()/poll() 或类似方法监视事件的文件描述符。
  • 在主循环中创建一个管道并监控它
  • write() 一个字节到信号处理程序中的管道
  • 运行您的代码来处理信号,包括在主循环检测到该管道上的事件时保护任何共享数据

  • 或者
  • 留一条备用线
  • 阻止所有线程中的给定信号
  • 在使用信号掩码调用 sigsuspend() 时让空闲线程循环确保该信号的传递。
  • 运行您的代码,包括保护任何共享数据以在 sigsuspend() 返回时处理信号
  • 关于multithreading - 在 linux 中信号处理程序的执行是不可抢占的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6128547/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com