【问题标题】:Is possible read half size of object happen in multi-thread?多线程中是否可能读取对象的一半大小?
【发布时间】:2019-08-15 06:03:29
【问题描述】:

有两个线程,一个产品数据,另一个过程数据。 数据不仅仅是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?有关

【问题讨论】:

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


    【解决方案1】:

    一旦你有一个线程修改一个对象,而另一个线程可能同时访问同一个对象的值,你就有一个race condition 并且行为是未定义的。是的,这可能发生。而且,由于我们在这里讨论的是像整个图像缓冲区这样的对象,几乎肯定会发生。是的,您需要使用适当的同步来防止它发生。

    根据您的描述,您似乎基本上遇到了这样一种情况:一个线程正在生成一些图像,而另一个线程必须等待图像准备好。在这种情况下,您应该问自己的第一个问题是:如果第二个线程在第一个线程完成工作之前无法开始工作,那么在这里使用第二个线程到底有什么好处?如果仍然有足够的工作让两个线程可以并行执行以使这一切变得有意义,那么您很可能不仅要在此处使用简单的互斥锁,还需要更多类似的东西,例如 condition variable 或 @987654323 @…

    【讨论】:

    • 谢谢,我更新了问题。请你看一下。
    • 当您(有用地)使用任何同步原语(如互斥锁)时,竞争条件是不可避免的:哪个线程锁定互斥锁是不可预测的。
    • 研究术语——双缓冲(在计算机图形学中)
    猜你喜欢
    • 1970-01-01
    • 2011-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-26
    • 1970-01-01
    • 2015-07-17
    • 2014-06-28
    相关资源
    最近更新 更多