全局变量不会在信号处理程序中更新,除非是像
sig_atomic_t
这样的原子类型。考虑到以下两个条件,我可以安全地编辑信号处理程序中的全局变量吗?
sa_mask
的 struct sigaction
来阻止处理程序的所有信号添加更多细节: 我有一个小的全局链接列表,其中保存了其子进程的一些信息。一旦我捕获 SIGCHLD (在父进程中),在我的信号处理程序中,我想从链接列表中删除该节点。 我可以在具有上述条件的信号处理程序中执行此操作并使用某种 pthread_mutex_trylock() 吗?
信号处理程序在访问静态数据结构时存在问题。 由此,您可以获得损坏的数据等。 如果您尝试在信号处理程序中调用 printf(),很多时候您会得到奇怪的输出。
全局变量也是如此,除非您使用原子类型。
类型
sig_atomic_t
肯定会更新。您不能依赖于信号处理程序上下文之外的任何其他类型进行更新。可能是,并且绝对不能保证它不会更新。然而,这归结为缓存和多处理器、异步执行和其他类似事情的处理。如果编译器认为变量不会改变,它可能会将其加载到寄存器中并且永远不会重新加载它。这对于sig_atomic_t
来说是不允许的,所以它“不会出错”。
这类似于“在不同线程中更新全局变量”,更新需要在锁下或使用特殊的原子类型来完成。您不能在信号处理程序中使用锁,因为当持有某些锁时可以调用信号处理程序!
这里可能需要一个信号处理线程。您必须在主线程中阻止 SIGCHLD。启动后在信号处理线程中将其解锁。您的列表必须通过锁定等方式进行保护。您准备好这样做了吗?