Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 信号和信号量系统V_C_Unix_Signals_Mutex_Semaphore - Fatal编程技术网

C 信号和信号量系统V

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

我正在用C语言在Unix上编程

我有3个关键区域:

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);
    }
}