Pthread生产者/消费者使用select()调用文件I / O.

时间:2013-10-23 23:15:25

标签: c opencv pthreads posix posix-select

我正在尝试提高我正在使用OpenCV在嵌入式Linux计算机上运行的实时计算机视觉程序的捕获性能。我想使用多个线程和共享内存缓冲区来分离(1)捕获视频帧和(2)处理它们的任务(我相信“生产者/消费者问题”)。我已经阅读了pthreads,互斥变量和条件变量,但不明白它们如何与select()函数一起使用。

现在,使用Video4Linux2 Video Capture Example改编的代码捕获视频帧,该代码使用select()。据我了解,select()阻止程序,直到网络摄像头可以获得数据,这可能很慢并且浪费时间。如果可能的话,我想使用那些浪费的CPU周期来处理图像处理。 (当然这意味着处理总是必须在一帧“陈旧”的图像上完成,但是以30 fps的速度实际上它将是实时的。)

我发现有些example code使用pthread_mutex_lock()pthread_mutex_control()来保护共享数据,但是似乎这些仍会阻止“处理”线程在等待时运行通过select() 获取图片数据。更具体地说,这里有一些伪代码来说明我的担忧。 (注意:我意识到这些线程需要包含循环和其他检查,如上面链接的示例才能真正正常工作。)

void* capture()
{
    pthread_mutex_lock(&mutex);             // protect shared data
    pthread_cond_wait(&space_avail,&mutex); // make sure the buffer has room

    ///  capture code... ///

    select(fd+1, &fds, NULL, NULL, &tv);  // waiting for data...
                                          // Want to be processing frames
                                          // during select, but won't the
                                          // processing thread be blocked
                                          // by the mutex lock?

    // store image to the frame buffer

    /// more capture code... ///

    pthread_cond_signal(&data_avail);
    pthread_mutex_unlock(&mutex);
}


void* process()
    pthread_mutex_lock(&mutex);
    pthread_cond_wait(&data_avail);

    // access the most recently stored frame from the buffer

    /// Do image processing ///

    pthread_mutex_signal(&space_avail);
    pthread_mutex_unlock(&mutex);
}

1 个答案:

答案 0 :(得分:0)

如果我已正确理解您的问题,您希望避免在程序等待选择时浪费的繁忙等待周期,并将其用于图像处理。如果我错了,请纠正我。

根据我的经验,执行此操作的一种简单方法是为select API指定一个小超时。 Select API将等待此时间。如果在此持续时间内它从网络摄像头接收到任何数据,则select的返回值将不为零。如果在该持续时间内没有看到任何有趣的内容,则返回值将为0.

所以您的伪代码可以修改为以下内容:

void* capture(){
    while(true){//iterate how many times you feel it is valid to
        if (select(fd+1, &fds, NULL, NULL, &tv)!=0){
              //We have found something here.take data from the webcam.
              //break from the loop.
              break;
         }else{
              //timeout occurred. process the image.
         }
     }
     //process the data from the webcam
}

如果这可以解决您的问题,请告诉我。有关Select API的更多信息,请访问: http://linux.die.net/man/2/select