首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >信号安全使用sem_wait()/sem_post()

信号安全使用sem_wait()/sem_post()
EN

Stack Overflow用户
提问于 2009-06-01 23:24:21
回答 3查看 14.7K关注 0票数 4

我正在尝试在Linux上创建一个包装器,它控制同时允许多少个并发执行的东西。为此,我使用了一个系统范围的计数信号量。我创建信号量,执行sem_wait(),启动子进程,然后在子进程终止时执行sem_post()。这很好。

问题是如何安全地处理发送到此包装器的信号。如果它没有捕捉到信号,该命令可能会在不执行sem_post()的情况下终止,从而导致信号量计数永久减少1。因此,我创建了一个执行sem_post()的信号处理程序。但是,仍然存在一个问题。

如果在执行sem_wait()之前附加了处理程序,则信号可能会在sem_wait()完成之前到达,从而导致在没有sem_wait()的情况下发生sem_post()。如果我在设置信号处理程序之前执行sem_wait(),则可以进行相反的操作。

显而易见的下一步是在设置处理程序和sem_wait()期间阻止信号。这是我现在所拥有的伪代码:

代码语言:javascript
复制
void handler(int sig)
{
  sem_post(sem);
  exit(1);
}

...
sigprocmask(...);   /* Block signals */
sigaction(...);     /* Set signal handler */
sem_wait(sem);
sigprocmask(...);   /* Unblock signals */
RunChild();
sem_post(sem);
exit(0);

现在的问题是sem_wait()可能会阻塞,在此期间,信号会被阻塞。试图终止进程的用户最终可能会求助于"kill -9“,这是我不想鼓励的行为,因为我无论如何都无法处理这种情况。我可以在一小段时间内使用sem_trywait()并测试sigpending(),但这会影响公平性,因为不再能保证等待信号量时间最长的进程下一步会运行。

这里有没有一个真正安全的解决方案,允许我在获取信号量的过程中处理信号?我正在考虑求助于“我是否有信号量”全局函数并移除信号阻塞,但这并不是100%安全的,因为获取信号量并设置全局函数不是原子的,但可能比在等待时阻塞信号要好。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2009-06-01 23:39:38

您确定sem_wait()导致信号被阻止吗?我认为情况并非如此。man page for sem_wait()表示,如果被信号中断,则从sem_wait()返回EINTR错误代码。

您应该能够处理此错误代码,然后您的信号将被接收。您是否遇到过信号未被接收到的情况?

我会确保您处理sem_wait()可以返回的错误代码。尽管这可能很少见,但如果你想100%确定你想要100%地覆盖你的基础。

票数 7
EN

Stack Overflow用户

发布于 2009-06-02 00:04:22

你确定你处理这个问题是正确的吗?如果您想等到子进程终止,则可能需要使用waitpid()系统调用。正如您所观察到的,如果孩子可能接收到信号,那么期望它做sem_post()是不可靠的。

票数 0
EN

Stack Overflow用户

发布于 2012-10-12 06:40:02

我知道这很古老,但为了那些仍在阅读谷歌提供的这篇文章的人的利益…

最简单的(也是唯一的?)这个问题的健壮解决方案是使用System V信号量,它允许客户端以内核自动返回的方式获取信号量资源,无论进程如何退出。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/937289

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档