gpt4 book ai didi

c - 所需的sigsuspend的说明

转载 作者:太空狗 更新时间:2023-10-29 16:47:42 26 4
gpt4 key购买 nike

我需要对sigsuspend主题进行澄清。
我有一个简化的例子

sigset_t mask, oldmask;
sigemptyset (&mask);
sigaddset (&mask, SIGRTMIN+1);
sigprocmask (SIG_BLOCK, &mask, &oldmask);

sigsuspend(&oldmask);

sigprocmask (SIG_UNBLOCK, &mask, NULL);

这是我的理解:

  • sigemptyset清除信号列表(掩码)-因为它是用当前被阻止的信号(?)初始化的

  • sigaddset将SIGRTMIN + 1添加到掩码
  • sigprocmask将mask + oldmask中的所有信号设置为被阻止
  • sigsuspend(&oldmask)暂停线程执行,直到被阻止的信号之一到达为止?如果要阻止SIGRTMIN + 1,应该不存在sigsuspend(&mask)吗?

    其次,让我们假设我有一个这样的信号暂挂,并且到达了几个SIGRTMIN + 1信号。每个信号都会继续这样的循环吗?在某种队列中?
    while(1){
    sigsuspend(&oldmask)
    printf("recieved signal");
    }

    这样我就为每个信号打印了“接收到的信号”?
  • 最佳答案

    此答案的上一版本的主要部分有误。我为我的错误道歉。感谢Wotim指出错误。

    POSIX的sigsuspend()的定义

    POSIX标准相当清楚地描述了 sigsuspend() :

    #include <signal.h>

    int sigsuspend(const sigset_t *sigmask);

    DESCRIPTION

    The sigsuspend() function shall replace the current signal mask of the calling thread with the set of signals pointed to by sigmask and then suspend the thread until delivery of a signal whose action is either to execute a signal-catching function or to terminate the process. This shall not cause any other signals that may have been pending on the process to become pending on the thread.

    If the action is to terminate the process then sigsuspend() shall never return. If the action is to execute a signal-catching function, then sigsuspend() shall return after the signal-catching function returns, with the signal mask restored to the set that existed prior to the sigsuspend() call.

    It is not possible to block signals that cannot be ignored. This is enforced by the system without causing an error to be indicated.

    RETURN VALUE

    Since sigsuspend() suspends thread execution indefinitely, there is no successful completion return value. If a return occurs, -1 shall be returned and errno set to indicate the error.

    ERRORS

    The sigsuspend() function shall fail if:

    [EINTR] A signal is caught by the calling process and control is returned from the signal-catching function.



    另外,POSIX Signal concepts表示:

    Each thread has a "signal mask" that defines the set of signals currently blocked from delivery to it.



    应用到您的代码片段
    sigsuspend()函数是旧 pause() 函数的现代类似物。

    重大变化:反转两个代码块。

    它使您可以让线程进入休眠状态,直到出现其选定的信号之一。如果您希望它在SIGRTMIN + 1到达之前就进入休眠状态,则可以使用:
    sigfillset(&mask);
    sigdelset(&mask, SIGRTMIN+1);
    sigsuspend(&mask);

    这将阻止除SIGRTMIN + 1之外的所有信号。

    如果您想在SIGRTMIN + 1以外的信号到达之前休眠,请使用:
    sigemptyset(&mask);
    sigaddset(&mask, SIGRTMIN+1);
    sigsuspend(&mask);

    这仅阻止SIGRTMIN + 1。

    除非您在末尾添加换行符,否则循环将无法可靠地打印 Received signal(甚至可能不会;否则,您可能需要 fflush(stdout)或同等功能)。但是,如果您在正常事件过程中阻止了SIGRTMIN + 1,然后将 &oldmask设置为仅允许SIGRTMIN + 1,那么当您的代码位于 sigsuspend()中时,信号将被可靠地传递。

    您对 sigprocmask() 的描述不正确:

    sigprocmask sets all signals in mask+oldmask to be blocked



    当您这样做时:
    sigset_t mask, oldmask;
    sigemptyset(&mask);
    sigaddset(&mask, SIGRTMIN+1);
    sigprocmask(SIG_BLOCK, &mask, &oldmask);

    您将SIGRTMIN + 1添加到阻止信号列表中(因为您使用了SIG_BLOCK,而 mask仅包含SIGRTMIN + 1)。 oldmask中的输出是添加SIGRTMIN + 1之前的信号掩码。它可能包含或可能尚未包含SIGRTMIN + 1。进程的信号掩码从当前值更改为包含SIGRTMIN + 1的新值(如果需要为线程设置信号掩码,请改用 pthread_sigprocmask()),并告知您旧值。

    从评论

    So is it wrong to use sigsuspend(&oldmask) as in my first example if I want to block SIGRTMIN+1?



    重大变化。

    是的,这是错误的。调用 sigsuspend(&oldmask)会使您的线程进入休眠状态,直到收到 oldmask中的信号之一。 oldmask的内容是在添加SIGRTMIN + 1之前被阻止的一组信号。

    是的,这是错误的。调用 sigsuspend(&oldmask)会使您的线程进入休眠状态,直到收到 oldmask中未包含的信号之一。 oldmask的内容是在添加SIGRTMIN + 1之前被阻止的一组信号。

    以下两段被撤回,而不一定被谴责为错误的。我认为两者都有真理,尽管两者都有改进的余地。

    您本身并不使用 sigsuspend()来阻止信号;您可以使用它来等待一组指定的信号之一到达。

    如果要忽略SIGRTMIN + 1,则需要使用 sigaction()或使用 sigprocmask();专门阻止SIGRTMIN + 1以及已经被阻止的所有其他信号。

    Do I understand correctly that it will block the same signals the way it was?



    假设它是 sigsuspend(),那么它将阻止 oldmask中没有的任何信号,并等待 oldmask中的信号之一到达。

    假设它是 sigsuspend(),那么它将阻止 oldmask中的任何信号,并等待非 oldmask中的信号之一到达。

    And if I do sigsuspend(&mask) then it will block SIGRTMIN+1 and all of the signals in oldmask because of sigprocmask(SIG_BLOCK, &mask, &oldmask)?



    重大变化

    绝对不!这将暂停线程,直到 mask中的信号之一到达。由于 mask中唯一的信号是SIGRTMIN + 1,因此只有在到达时 sigsuspend()才会返回。 sigprocmask()oldmask中报告了在调用之前被阻止的内容;它根本没有修改 mask(您的变量);它确实通过添加SIGRTMIN + 1来修改了进程的信号掩码。

    绝对不!这将挂起线程,直到 mask中没有的信号之一到达为止。由于 mask中的唯一信号是SIGRTMIN + 1,因此只有该信号被阻止,并且当任何其他信号到达时,它将被处理,并且 sigsuspend()将返回。 sigprocmask()oldmask中报告了在调用之前被阻止的内容;它根本没有修改 mask(您的变量);它确实通过添加SIGRTMIN + 1来修改了进程的信号掩码。

    我强烈建议阅读或重新阅读POSIX Signal concepts以及操纵信号处理的各种功能。 (是的,这在某种程度上是“医生,要自愈”的处方。)

    如果这里仍然有错误,请告诉我。

    关于c - 所需的sigsuspend的说明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15283934/

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