Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/28.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_Linux_Signals_Semaphore - Fatal编程技术网

C 为什么先封锁信号,然后再解除封锁?

C 为什么先封锁信号,然后再解除封锁?,c,linux,signals,semaphore,C,Linux,Signals,Semaphore,在阅读涉及v4l2 API的某些源代码时,我偶然发现了以下几部分: 第一: sigemptyset(&set); sigaddset(&set, SIGCHLD); sigaddset(&set, SIGALRM); sigaddset(&set, SIGUSR1); sigaddset(&set, SIGTERM); sigaddset(&set, SIGHUP); pthread_sigmask(SIG_BLOCK, &set, &am

在阅读涉及v4l2 API的某些源代码时,我偶然发现了以下几部分:

第一:

sigemptyset(&set);
sigaddset(&set, SIGCHLD);
sigaddset(&set, SIGALRM);
sigaddset(&set, SIGUSR1);
sigaddset(&set, SIGTERM);
sigaddset(&set, SIGHUP);
pthread_sigmask(SIG_BLOCK, &set, &old);
然后:

其间:

if (s->pframe >= 0) {
    if (xioctl(s->fd, VIDIOC_QBUF, &s->buf) == -1) {
        motion_log(LOG_ERR, 1, "%s: VIDIOC_QBUF", __FUNCTION__);
        return -1;
    }
}

memset(&s->buf, 0, sizeof(struct v4l2_buffer));

s->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
s->buf.memory = V4L2_MEMORY_MMAP;

if (xioctl(s->fd, VIDIOC_DQBUF, &s->buf) == -1) {

    /* some drivers return EIO when there is no signal, 
       driver might dequeue an (empty) buffer despite
       returning an error, or even stop capturing.
    */
    if (errno == EIO) {
        s->pframe++; 
        if ((u32)s->pframe >= s->req.count) s->pframe = 0;
        s->buf.index = s->pframe;

        motion_log(LOG_ERR, 1, "%s: VIDIOC_DQBUF: EIO (s->pframe %d)", __FUNCTION__, s->pframe);

        return 1;
    }

    motion_log(LOG_ERR, 1, "%s: VIDIOC_DQBUF", __FUNCTION__);

    return -1;
}

s->pframe = s->buf.index;
s->buffers[s->buf.index].used = s->buf.bytesused;
s->buffers[s->buf.index].content_length = s->buf.bytesused;
我诚实的猜测是,在这种特殊情况下,阻塞信号可以防止设置过程被中断。但我完全不确定。请帮忙?

您的猜测是正确的,它应该可以防止线程中断。 上面的链接并不特定于pthreads,但其概念是相同的,我认为已经很好地解释了

编辑: pthreads关于阻塞信号的解释

您的猜测是正确的,它应该可以防止线程中断。 上面的链接并不特定于pthreads,但其概念是相同的,我认为已经很好地解释了

编辑: pthreads关于阻塞信号的解释

您能按实际顺序显示代码吗?把中间的代码放在另一个代码之后是令人困惑的。你的猜测在我看来是正确的。它会阻止这些信号,进行设置,然后将信号掩码恢复到以前的状态。我猜您不想让视频缓冲区处于中间状态,部分初始化。您能按实际顺序显示代码吗?把中间的代码放在另一个代码之后是令人困惑的。你的猜测在我看来是正确的。它会阻塞这些信号,进行设置,然后将信号掩码恢复到以前的状态。我猜您不希望视频缓冲区处于中间状态,部分初始化。
if (s->pframe >= 0) {
    if (xioctl(s->fd, VIDIOC_QBUF, &s->buf) == -1) {
        motion_log(LOG_ERR, 1, "%s: VIDIOC_QBUF", __FUNCTION__);
        return -1;
    }
}

memset(&s->buf, 0, sizeof(struct v4l2_buffer));

s->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
s->buf.memory = V4L2_MEMORY_MMAP;

if (xioctl(s->fd, VIDIOC_DQBUF, &s->buf) == -1) {

    /* some drivers return EIO when there is no signal, 
       driver might dequeue an (empty) buffer despite
       returning an error, or even stop capturing.
    */
    if (errno == EIO) {
        s->pframe++; 
        if ((u32)s->pframe >= s->req.count) s->pframe = 0;
        s->buf.index = s->pframe;

        motion_log(LOG_ERR, 1, "%s: VIDIOC_DQBUF: EIO (s->pframe %d)", __FUNCTION__, s->pframe);

        return 1;
    }

    motion_log(LOG_ERR, 1, "%s: VIDIOC_DQBUF", __FUNCTION__);

    return -1;
}

s->pframe = s->buf.index;
s->buffers[s->buf.index].used = s->buf.bytesused;
s->buffers[s->buf.index].content_length = s->buf.bytesused;