这是我班上的课程。我不确定我的答案是否正确。有人可以给我任何指示。在第一个问题中,我无法弄清楚为什么存在竞争条件,我的解释是错误的吗?
#include <signal.h>
#include <unistd.h>
#include <sys/wait.h>
void sigHandler(int signo) {
/* Line C */
}
int main() {
pid_t pid;
sigset_t newmask, waitmask, oldmask;
if ((pid = fork()) == 0) { // Child
struct sigaction action;
sigemptyset(&newmask);
sigemptyset(&waitmask);
sigaddset(&newmask, SIGUSR1);
sigaddset(&waitmask, SIGUSR2);
sigprocmask(SIG_BLOCK, &newmask, &oldmask);
action.sa_flags = 0;
sigemptyset(&action.sa_mask);
action.sa_handler = sigHandler;
sigaction(SIGUSR2, &action, NULL);
sigaction(SIGINT, &action, NULL);
sigaddset(&action.sa_mask, SIGINT);
sigaction(SIGUSR1, &action, NULL);
/* Line A: critical section */
sigsuspend(&waitmask); /* Line B */
} else { // Parent
int stat;
kill(pid, SIGUSR1);
kill(pid, SIGUSR2);
kill(pid, SIGINT);
pid = wait(&stat);
}
return 0;
}
sigsuspend()
,但仍然存在竞争条件。为什么?因为我们不知道父进程何时首先执行或子进程执行。如果父级首先执行,则父级会向子级发送SIGUSR1
,SIGUSR2
和SIGINT
,因为SIGUSR1
现已被阻止,SIGUSR2
和{{1}将被正确捕获,但我们会SIGINT
,这意味着以下行sigaddset(&action.sa_mask, SIGINT)
将阻止sigaction(SIGUSR1, &action, NULL)
和SIGUSR1
。最后,B行调用SIGINT
,它将等待除sigsuspend(&waitmask)
之外的信号。但这是我的问题:由于SIGUSR2
没有阻止sigsuspend(&waitmask)
,为什么还有竞争条件? SIGUSR1
和SIGUSR2
是否已被捕获?
SIGINT
,在第B行收到{b} SIGUSR2
,在SIGINT
时收到{c} SIGUSR1
抓住C线,孩子如何处理&#39;信号掩码变化?解释你的答案。(a)面具包含SIGINT
(SIGUSR1
}和sigprocmask()
(SIGINT
)。
(b)掩码仅包含sigaddset()
(SIGUSR2
个)。
在sigsuspend()
之后,面具会恢复为sigsuspend()
和SIGUSR1
。
(c)面具包含SIGINT
和SIGINT
,因此它会阻止SIGUSR1
。
SIGUSR1
,在第B行收到{b} SIGUSR1
,在SIGUSR2
时收到{c} SIGINT
抓住C线,孩子如何处理&#39;信号掩码变化?解释你的答案。(a)掩码包含SIGUSR1
(SIGUSR1
}和sigprocmask()
(SIGINT
),sigaddset()
被阻止。
(b)掩码仅包含SIGUSR1
(SIGUSR2
个)。
在sigsuspend()
之后,面具会恢复为sigsuspend()
和SIGUSR1
。
(c)面具包含SIGINT
和SIGINT
,因此它会阻止SIGUSR1
。