在多线程中可能会读取一半大小的对象吗?

时间:2019-03-25 01:42:28

标签: c++ multithreading opencv parallel-processing thread-safety

具有两个线程,一个是产品数据,另一个是过程数据。 数据不仅是intfloat,而且是一个复杂的对象。就我而言,它是OpenCV Mat(图片)。 如果第一个线程仅创建了图像大小的一半,而第二个线程读取了它,是否将获得图像的一半大小?图片会损坏吗?

int main(int argc, char *argv[])
{
    cv::Mat buffer;
    cv::VideoCapture cap;
    std::mutex mutex;
    cap.open(0);
    std::thread product([](cv::Mat& buffer, cv::VideoCapture cap, std::mutex& mutex){
        while (true) { // keep product the new image
            cv::Mat tmp;
            cap >> tmp;
            //mutex.lock();
            buffer = tmp.clone();
            //mutex.unlock();
        }
    }, std::ref(buffer), cap, std::ref(mutex));
    product.detach();
    int i;
    while (true) { // process in the main thread
        //mutex.lock();
        cv::Mat tmp = buffer;
        //mutex.unlock();
        if(!tmp.data)
            std::cout<<"null"<<i++<<std::endl;
        else {
            //std::cout<<"not null"<<std::endl;
            cv::imshow("test", tmp);
        }
        if(cv::waitKey(30) >= 0) break;
    }
    return 0;
}

我是否需要在读写周围添加互斥体以确保图像不被破坏?像这样:

int main(int argc, char *argv[])
{
    cv::Mat buffer;
    cv::VideoCapture cap;
    std::mutex mutex;
    cap.open(0);
    std::thread product([](cv::Mat& buffer, cv::VideoCapture cap, std::mutex& mutex){
        while (true) { // keep product the new image
            cv::Mat tmp;
            cap >> tmp;
            mutex.lock();
            buffer = tmp.clone();
            mutex.unlock();
        }
    }, std::ref(buffer), cap, std::ref(mutex));
    product.detach();

    while (true) { // process in the main thread
        mutex.lock();
        cv::Mat tmp = buffer;
        mutex.unlock();
        if(!tmp.data)
            std::cout<<"null"<<std::endl;
        else {
            std::cout<<"not null"<<std::endl;
            cv::imshow("test", tmp);
        }

    }
    return 0;
}

该问题与How to solves image processing cause camera io delay?

有关

1 个答案:

答案 0 :(得分:1)

一旦一个线程修改了一个对象,而另一个线程潜在地并发访问了同一对象的值,您将拥有一个race condition并且行为是不确定的。是的,可能会发生。而且,由于我们在这里谈论的对象是整个图像缓冲区,因此几乎可以肯定会发生。是的,您将需要使用适当的同步来防止它发生。

根据您的描述,似乎您基本上处于一种情况,其中一个线程正在生成某些图像,而另一个线程必须等待该图像准备就绪。在这种情况下,您应该问自己的第一个问题是:如果第二个线程在第一个线程完成工作之前无法开始工作,那么您在这里使用第二个线程究竟能获得什么呢?如果仍有足够的工作使两个线程可以并行执行所有操作,那么您很可能不仅希望在这里使用简单的互斥锁,还应该使用诸如condition variablebarrier