C 信号和信号量系统V
我正在用C语言在Unix上编程 我有3个关键区域:C 信号和信号量系统V,c,unix,signals,mutex,semaphore,C,Unix,Signals,Mutex,Semaphore,我正在用C语言在Unix上编程 我有3个关键区域: Mutex1 -> Lock { { ZONE1 { Mutex1 -> unLock Mutex2 -> Lock { { ZONE2 { Mutex2 -> unLock Mutex3 -> Lock { { ZONE3 { Mutex3 -> unLock 对于每个区域,都有一个互斥锁。N个进程执行此代码,因此需要互斥体来管理关键区域。 我的问题是: SIGINT是这样处理的->信号(SIGINT
Mutex1 -> Lock
{
{ ZONE1
{
Mutex1 -> unLock
Mutex2 -> Lock
{
{ ZONE2
{
Mutex2 -> unLock
Mutex3 -> Lock
{
{ ZONE3
{
Mutex3 -> unLock
对于每个区域,都有一个互斥锁。N个进程执行此代码,因此需要互斥体来管理关键区域。
我的问题是:
SIGINT是这样处理的->信号(SIGINT,handler)
如果一个进程在一个关键区域中收到信号(例如ctrl+c),我需要解锁互斥锁,只需考虑进程接收信号时的位置(区域1、区域2或区域3)
我可以怎么做呢?一个选项是使用sigprocmask()阻止关键部分周围的信号。这样可以将信号响应限制在非关键区域 如果您需要信号来影响您的关键部分,那么您可以与信号处理程序a la进行通信:
volatile sigstate;
void handler(int signo) {
if (sigstate & 1) {
sigdefcount++;
} else {
_exit(1);
}
}
请注意,从信号处理程序调用exit()是不安全的;它必须是_exit()。这样,关键部分中的代码应该设置sigstate标志,并定期检查计数。这很快就会变得复杂,因为许多系统调用默认情况下会在中断时安静地重新启动,并且您可能需要用超时阻塞接口,以便您可以检查此指示器
在大多数情况下,最好简化关键部分,使其具有可预测的执行时间,并禁用其中的信号。这可能涉及将一些关键部分拆分为子部分,如果再多做一点工作,这可能是一个更清晰的设计。设置一个变量,指示您将要进入的关键区域,并解锁相关的互斥锁。当然,这将是一个全局变量。但是,当您的进程退出时,应该解锁互斥锁,除非您使用的互斥锁类型不是POSIX类型。您尚未指定如何实现互斥体。你可以让SystemV IPC撤销进程退出时所做的信号量操作。分配变量不是原子的。但您一次只能在一个区域中,不是吗?因此,当您切换到一个区域时,如果您之前设置了变量,最坏的情况下,您将尝试解锁未锁定的互斥锁,这将失败。解锁互斥锁后,立即将'which zone'变量设置回'none'。如果我在处理程序上解锁互斥锁(因此我执行semop),在这种情况下,我会遇到一个大问题OK;然后您可能需要展示互斥体的实现,或者您可能需要澄清您计划做什么,而不是
exit(0)代码>(这可能不是一个好的退出状态-它意味着“成功”-当您的进程因中断而停止时)。或者我可能需要停止尝试帮助,因为我似乎不了解你的情况。信号处理是不确定的-处理跨进程协调的信号更难。您是否考虑过使用多线程实现而不是多处理实现?这是我想到的唯一解决方案。难道不存在另一个吗?不容易,但如果您的进程遵循类似于分派的模式,并使用select作为基本的等待事件机制,则pselect允许使用信号掩码来提高这种模式的效率。
volatile sigstate;
void handler(int signo) {
if (sigstate & 1) {
sigdefcount++;
} else {
_exit(1);
}
}