-1

Having two thread, one product data, another one process data. The data is not just an int or float but a complex object. In my case, it's an OpenCV Mat(an image). If the first thread only created half-size of the image, and second thread read it, will get half size of the image? The image will be broken?

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;
}

Do I need to add a mutex around write and read to make sure the image not be broken? Like this:

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;
}

This question related to How to solves image processing cause camera io delay?

JustWe
  • 4,250
  • 3
  • 39
  • 90

1 Answers1

1

As soon as you have one thread modifying an object while another thread potentially accesses the value of that same object concurrently, you have a race condition and behavior is undefined. Yes, that can happen. And, since we're talking about an object like an entire image buffer here, almost certainly will happen. And yes, you will need to use proper synchronization to prevent it from happening.

From your description, it would seem that you basically have a situation here where one thread is producing some image and another thread has to wait for the image to be ready. In this case, the first question that you should ask yourself is: if the second thread cannot start its work before the first thread has completed its work, then what exactly are you gaining by using a second thread here? If there is still enough work that both threads can do in parallel for this all to make sense, then you will most likely want to use not just a simple mutex here, but more something like, e.g., a condition variable or a barrier

Michael Kenzel
  • 15,508
  • 2
  • 30
  • 39