Возможно ли считывание половины размера объекта в многопоточности? - PullRequest
0 голосов
/ 25 марта 2019

Имеет два потока, один данные продукта, другой данные процесса.Данные - это не просто int или float, а сложный объект.В моем случае это 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;
}

Этот вопрос относится к Как решить, обработка изображения вызывает задержку io камеры?

1 Ответ

1 голос
/ 25 марта 2019

Как только у вас есть один поток, модифицирующий объект, в то время как другой поток потенциально получает доступ к значению этого же объекта одновременно, вы получаете условие гонки и поведение не определено.Да, это может случиться.И, поскольку мы говорим об объекте, подобном целому буферу изображений, почти наверняка произойдет.И да, вам нужно будет использовать правильную синхронизацию, чтобы не допустить этого.

Из вашего описания может показаться, что у вас в основном возникает ситуация, когда один поток создает какое-то изображение, а другой поток должен ждатьизображение будет готово.В этом случае первый вопрос, который вы должны задать себе: если второй поток не может начать свою работу до того, как первый поток завершит свою работу, то что именно вы получаете, используя второй поток здесь?Если по-прежнему достаточно работы, которую оба потока могут выполнять параллельно, чтобы все это имело смысл, то вы, скорее всего, захотите использовать здесь не просто мьютекс, а что-то вроде, например, условной переменной или барьер

...