【发布时间】:2012-04-15 17:27:22
【问题描述】:
我正在为系统课程的 shell 实验室工作,自周五晚上以来我一直在尝试解决一些非常奇怪的竞态条件错误,但似乎无法确定。
我当前的代码:http://buu700.com/tsh
START OF MY CODE 之前和END OF MY CODE 之后的所有内容均由课程讲师提供,因此这些都不应该是问题的根源。
我们也有一个测试脚本;这是我当前测试结果的输出: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;
}
【问题讨论】:
-
我发现你对教授提供的代码的信心可爱。 :)
-
哈哈,对我来说,这看起来是相当可靠的代码,而且大多数学生已经完成了实验,因此课程提供的代码可以正常工作。 (据我所知,实际上没有一篇是我的两位教授亲自写的。)
-
您能否更好地描述故障。并解释为什么你认为这是一种竞争条件?
标签: c shell system signals race-condition