gpt4 book ai didi

c - 我的信号处理程序中的竞争条件? (C)

转载 作者:太空宇宙 更新时间:2023-11-04 04:02:41 25 4
gpt4 key购买 nike

我正在系统类(class)的 shell 实验室工作,我遇到了一些非常奇怪的竞争条件错误,自周五晚上以来我一直试图解决这些错误,但似乎无法确定。

我当前的代码:http://buu700.com/tsh

START OF MY CODE 之前的所有内容在 END OF MY CODE 之后由类(class)讲师提供,因此这些都不是问题的根源。

我们也有一个测试脚本;这是我当前测试结果的输出:http://buu700.com/sdriver


/*****************
* Signal handlers
*****************/

/*
* sigchld_handler - The kernel sends a SIGCHLD to the shell whenever
* a child job terminates (becomes a zombie), or stops because it
* received a SIGSTOP, SIGTSTP, SIGTTIN or SIGTTOU signal. The
* handler reaps all available zombie children, but doesn't wait
* for any other currently running children to terminate.
*/
void
sigchld_handler(int sig)
{
pid_t pid;
int status, termsig;
struct job_t *job;


sigset_t s;

sigemptyset(&s);
sigaddset(&s, SIGCHLD);
sigaddset(&s, SIGINT);
sigaddset(&s, SIGTSTP);

sigprocmask(SIG_BLOCK, &s, NULL);


while ((pid = waitpid(-1, &status, WNOHANG | WUNTRACED)) > 0) {
if (WIFEXITED(status)) {
deletejob(job_list, pid);
}
if ((termsig = WTERMSIG(status))) {
deletejob(job_list, pid);
safe_printf("Job [%i] (%i) %s by signal %i\n",
pid2jid(pid), pid, "terminated", termsig);
}
if (WIFSTOPPED(status)) {
job = getjobpid(job_list, pid);
job->state = ST;
safe_printf("Job [%i] (%i) %s by signal %i\n",
pid2jid(pid), pid, "stopped", SIGTSTP);
}
}

if (errno != ECHILD)
unix_error("waitpid error");

sigprocmask(SIG_UNBLOCK, &s, NULL);

return;
}



/*
* sigint_handler - The kernel sends a SIGINT to the shell whenver the
* user types ctrl-c at the keyboard. Catch it and send it along
* to the foreground job.
*/
void
sigint_handler(int sig)
{
sigset_t s;

sigemptyset(&s);
sigaddset(&s, SIGCHLD);
sigaddset(&s, SIGINT);
sigaddset(&s, SIGTSTP);

sigprocmask(SIG_BLOCK, &s, NULL);

kill(-1, sig);

sigprocmask(SIG_UNBLOCK, &s, NULL);

return;
}



/*
* sigtstp_handler - The kernel sends a SIGTSTP to the shell whenever
* the user types ctrl-z at the keyboard. Catch it and suspend the
* foreground job by sending it a SIGTSTP.
*/
void
sigtstp_handler(int sig)
{
sigset_t s;

sigemptyset(&s);
sigaddset(&s, SIGCHLD);
sigaddset(&s, SIGINT);
sigaddset(&s, SIGTSTP);

sigprocmask(SIG_BLOCK, &s, NULL);

kill(-1, sig);

sigprocmask(SIG_UNBLOCK, &s, NULL);

return;
}

最佳答案

我怀疑这个错误来自于你在信号处理程序中与其他信号竞争:

sigint_handler(int sig) 
{
sigset_t s;

sigemptyset(&s);
sigaddset(&s, SIGCHLD);
sigaddset(&s, SIGINT);
sigaddset(&s, SIGTSTP);

sigprocmask(SIG_BLOCK, &s, NULL);

当您使用 sigaction(2) 注册信号处理程序时,您可以提供一个 sa_mask,当您的信号处理程序运行时,内核将使用它来为您阻止信号.这是自动完成的,不需要您做任何额外的工作。注册信号处理程序时只需填充此掩码一次。

另一种可能性来自SIGTSTP信号;我的副本第 350 页 APUE, 2nd edition部分说:

Only a job-control shell should reset the disposition of [SIGTSTP, SIGTTIN, SIGTTOU] to SIG_DFL.

那些段落中没有说,但我认为可以公平假设的是,shell 应该为 子进程 将信号处置设置为 SIG_DFL -- 它仍然需要做一些事情来处理信号本身。

您是否正确处理了子进程的信号处理?

关于c - 我的信号处理程序中的竞争条件? (C),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9969889/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com