我的信号处理器中的种族条件?(C)

我的信号处理器中的种族条件?(C),c,shell,system,signals,race-condition,C,Shell,System,Signals,Race Condition,我正在为一个系统课程在一个shell实验室工作,我一直有一些非常奇怪的种族条件错误,从周五晚上开始我就一直试图解决这些错误,但似乎无法确定 我当前的代码: 课程讲师提供了我的代码开始之前和结束之后的所有内容,因此这些内容都不应成为问题的根源 我们也有一个测试脚本;以下是我当前测试结果的输出: 我怀疑该错误来自于您与信号处理程序中的其他信号的竞争: sigint_handler(int sig) { sigset_t s; sigemptyset(&s); s

我正在为一个系统课程在一个shell实验室工作,我一直有一些非常奇怪的种族条件错误,从周五晚上开始我就一直试图解决这些错误,但似乎无法确定

我当前的代码:

课程讲师提供了我的代码开始之前和结束之后的所有内容,因此这些内容都不应成为问题的根源

我们也有一个测试脚本;以下是我当前测试结果的输出:



我怀疑该错误来自于您与信号处理程序中的其他信号的竞争:

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_掩码
,内核将使用该掩码在信号处理程序运行时为您阻止信号。这是以原子方式完成的,不需要您额外的工作。注册信号处理程序时只需填充此掩码一次

另一种可能性来自
SIGTSTP
信号;我的副本第350页部分说明:

只有作业控制外壳程序才应将[
SIGTSTP
SIGTTIN
SIGTTOU
]的处置重置为
SIG\U DFL

在这些段落中没有提到的是,我认为可以公平地假设,shell应该为子进程将信号配置设置为
SIG_DFL
——它仍然需要做一些事情来处理信号本身


您是否正确处理了孩子们的信号处理?

我怀疑该错误来自您与信号处理程序中其他信号的竞争:

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_掩码
,内核将使用该掩码在信号处理程序运行时为您阻止信号。这是以原子方式完成的,不需要您额外的工作。注册信号处理程序时只需填充此掩码一次

另一种可能性来自
SIGTSTP
信号;我的副本第350页部分说明:

只有作业控制外壳程序才应将[
SIGTSTP
SIGTTIN
SIGTTOU
]的处置重置为
SIG\U DFL

在这些段落中没有提到的是,我认为可以公平地假设,shell应该为子进程将信号配置设置为
SIG_DFL
——它仍然需要做一些事情来处理信号本身


你处理好孩子们的信号处理了吗?

我觉得你对教授提供的代码的信任很可爱。:)哈哈,对我来说,它看起来像是非常可靠的代码,而且大多数学生已经完成了实验,所以很明显,课程提供的代码是有效的。(但据我所知,没有一本是我的两位教授亲自写的。)你能更好地描述一下这个错误吗。并解释为什么你认为这是一个种族条件?我觉得你对教授提供的代码的信任很可爱。:)哈哈,对我来说,它看起来像是非常可靠的代码,而且大多数学生已经完成了实验,所以很明显,课程提供的代码是有效的。(但据我所知,没有一本是我的两位教授亲自写的。)你能更好地描述一下这个错误吗。并解释为什么你认为这是一种比赛状态?谢谢你的回答。课程提供的代码实际上有一个围绕sigaction的包装器,它按照您描述的方式处理阻塞;事实上,我只是把它作为一种随机的、毫无意义的东西扔进了处理程序中,人们在无目的地调试时往往会胡乱处理(它根本不会影响测试人员的输出)。我现在就删除它,因为它肯定不正确我还做了一些类似于调试时您对SIG_DFL的建议;这看起来接近正确吗?让我立刻感到害怕的是:
sprintf(cmd,“%s%s”,cmd,argv[i])。请注意
sprintf(3)
:C99和POSIX.1-2001中的警告规定,如果调用
sprintf()
snprintf()
vsprintf()
vsnprintf()
会导致在重叠的对象之间进行复制,则结果未定义(例如,如果目标字符串数组和提供的一个输入参数引用同一个缓冲区)。谢谢,刚刚解决了这个问题(我编写它时感觉很危险).我仍然从测试脚本中获得相同的输出,但这一部分现在应该更好了。感谢您的响应。课程提供的代码实际上有一个围绕sigaction的包装器,它按照您描述的方式处理阻塞;我实际上只是将其作为一个随机的无意义的东西扔进处理程序le漫无目的地调试(它根本不会影响测试仪的输出)。我现在将其删除,因为它肯定不正确。--我在调试时也做了一些类似于您建议的SIG_DFL的事情;这看起来接近正确吗?让我立即感到害怕的是:
sprintf(cmd,%s%s),cmd,argv[I])请注意
sprintf(3)
:C99和POSIX.1-2001中的警告:如果调用
sprintf()
snprintf()
vsprintf()
vsnprintf()
会导致在重叠的对象之间进行复制,则结果是未定义的(例如,如果目标字符串数组和提供的一个输入参数引用同一个缓冲区)。谢谢,刚刚修复了这个问题(我编写它时感觉很危险)。我仍然从测试脚本获得相同的输出,但这一部分现在应该更好了。