Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 需要解释这些问题_C_Unix_Process_Signals - Fatal编程技术网

C 需要解释这些问题

C 需要解释这些问题,c,unix,process,signals,C,Unix,Process,Signals,我需要澄清一下这个话题。 我有一个简单的例子 sigset_t mask, oldmask; sigemptyset (&mask); sigaddset (&mask, SIGRTMIN+1); sigprocmask (SIG_BLOCK, &mask, &oldmask); sigsuspend(&oldmask); sigprocmask (SIG_UNBLOCK, &mask, NULL); 我是这样理解的: SIGEPTYSET

我需要澄清一下这个话题。 我有一个简单的例子

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

sigsuspend(&oldmask);

sigprocmask (SIG_UNBLOCK, &mask, NULL);
我是这样理解的:
  • SIGEPTYSET清除信号列表(掩码)-因为它是用当前阻止的信号初始化的(?)
  • sigaddset将SIGRTMIN+1添加到掩码
  • sigprocmask将mask+OLDSMASK中的所有信号设置为阻塞
  • sigssuspend(&oldsmask)暂停线程执行,直到其中一个阻塞信号到达?如果我想阻止SIGRTMIN+1,不应该有sigssuspend(&mask)吗

    其次,假设我在一个循环中有这样的SIGSSUSPEND,并且有几个SIGRTMIN+1信号到达。对于每个信号,这样的循环会继续吗?在某种队列中

    while(1){
        sigsuspend(&oldmask)
        printf("recieved signal");
    }
    
    因此,对于我打印的每一个“接收信号”,上一版答案的主要部分都是错误的。我为我的错误道歉。谢谢你指出错误

    POSIX对
    SIGSSUSPEND()的定义
    POSIX标准相当清楚地描述了:

    #包括

    int-sigssuspend(const-sigset\u t*sigmask)

    描述

    SIGSTAND()
    函数应使用
    SIGSMASK
    所指向的一组信号替换调用线程的当前信号掩码,然后暂停线程,直到发送信号为止,该信号的作用是执行信号捕获函数或终止进程。这不会导致任何其他可能在进程上挂起的信号在线程上挂起

    如果操作是终止进程,则
    sigsupspend()
    将永远不会返回。如果操作是执行信号捕获函数,则在信号捕获函数返回后,
    sigsupspend()
    应返回,信号掩码恢复到调用
    sigsupspend()
    之前的设置

    无法阻止无法忽略的信号。这是由系统强制执行的,不会导致指示错误

    返回值

    由于
    sigssuspend()
    无限期挂起线程执行,因此没有成功完成返回值。如果发生返回,则应返回-1,并设置errno以指示错误

    错误

    如果出现以下情况,
    SIGSSUSPEND()
    功能将失败:

    [EINTR]
    调用进程捕获信号,并从信号捕获函数返回控制

    此外,POSIX说:

    每个线程都有一个“信号掩码”,用于定义当前阻止向其传递的信号集

    将应用程序添加到代码片段中
    sigssuspend()
    函数是旧函数的现代模拟

    主要变化:两个代码块颠倒

    它允许您将线程发送到睡眠状态,直到其中一个选定的信号出现。如果希望它一直休眠到SIGRTMIN+1到达,可以使用:

    sigfillset(&mask);
    sigdelset(&mask, SIGRTMIN+1);
    sigsuspend(&mask);
    
    sigemptyset(&mask);
    sigaddset(&mask, SIGRTMIN+1);
    sigsuspend(&mask);
    
    这将阻止除SIGRTMIN+1之外的所有信号

    如果您想一直睡眠到SIGRTMIN+1以外的信号到达,可以使用:

    sigfillset(&mask);
    sigdelset(&mask, SIGRTMIN+1);
    sigsuspend(&mask);
    
    sigemptyset(&mask);
    sigaddset(&mask, SIGRTMIN+1);
    sigsuspend(&mask);
    
    这仅阻止SIGRTMIN+1

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

    您对的描述不正确:

    sigprocmask
    设置要阻止的
    mask+oldsmask
    中的所有信号

    当您这样做时:

    sigset_t mask, oldmask;
    sigemptyset(&mask);
    sigaddset(&mask, SIGRTMIN+1);
    sigprocmask(SIG_BLOCK, &mask, &oldmask);
    
    您将SIGRTMIN+1添加到阻塞信号列表中(因为您使用了SIG_BLOCK,并且
    掩码
    仅包含SIGRTMIN+1)。
    oldmask
    中的输出是添加SIGRTMIN+1之前的信号掩码。它可能包含也可能不包含SIGRTMIN+1。进程的信号掩码将从当前值更改为包含SIGRTMIN+1的新值(如果需要为线程设置信号掩码,则使用
    pthread\u sigprocmask()
    ),然后您会被告知旧值

    从评论中 那么,如果我想阻止SIGRTMIN+1,那么在我的第一个示例中使用
    sigssuspend(&oldsmask)
    是错误的吗

    重大变化

    是的,这是错误的。调用
    sigssuspend(&oldsmask)
    会将线程发送到睡眠状态,直到收到
    oldsmask
    中的一个信号为止。
    oldmask
    的内容是在添加SIGRTMIN+1之前被阻止的信号集。

    是的,这是错误的。调用
    sigssuspend(&oldsmask)
    会将线程发送到睡眠状态,直到收到
    oldsmask
    中未包含的信号之一。
    oldmask
    的内容是在添加SIGRTMIN+1之前被阻止的信号集

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

    您不使用
    sigsupspend()
    来阻止信号本身;您使用它来等待一组指定的信号中的一个到达

    如果您想忽略SIGRTMIN+1,那么您需要使用
    sigaction()
    ,或者您可以像以前那样使用
    sigprocmask()
    ;它专门阻止SIGRTMIN+1以及所有其他已被阻止的信号。

    我是否正确理解,它会像以前那样阻止相同的信号

    假设“it”是
    sigssuspend()
    ,则它将阻止
    oldsmask
    中没有的任何信号,并等待
    oldsmask
    中的一个信号到达。

    假设“it”是
    sigssuspend()
    ,则它将阻止
    oldsmask
    中的任何信号,并等待
    oldsmask
    中没有的信号之一到达

    如果我做了
    sigsupspend(&mask)