C ++ std :: thread终止被调用而没有活动异常中止

我这里有一个代码,用于从在单独线程中运行视频捕获操作的摄像机捕获视频流。代码可以编译,但是当我尝试运行它时,我收到以下错误。

我做了一些研究,发现此问题与缺少th.join();有关,但是当用户通过按下q键中断该过程时,我已经这样做了。在此之前,代码应继续在创建的线程中运行。所以这告诉我应该在其他地方加入线程。

如果我通过将thread th(&VideoCaptureAsync::update,this);替换为VideoCaptureAsync::update();并删除th.join();来删除线程,则错误消失了,但这显然违反了此代码的目的。

输出

  

内部启动功能

     

(进程:10748):GStreamer-CRITICAL **:gst_element_get_state:   断言“ GST_IS_ELEMENT(元素)”失败

     

内部启动功能

     

内部更新功能

     

在没有活动异常的情况下终止调用

     

内部读取功能

     

已中止(核心已弃用)

代码

/*
* Asynchronous_video_capture.cpp
*
* Copyright (C) 2019 C. S. G.
*
* MIT License
*/

#include <iostream> // for standard I/O
#include <string>   // for strings
#include <opencv2/highgui.hpp>
#include <opencv2/core.hpp>     // Basic OpenCV structures (cv::Mat)
#include <opencv2/videoio.hpp>  // Video write
#include <opencv2/opencv.hpp>
#include <opencv2/core/utility.hpp>
#include <thread>
#include <tuple>

using namespace cv;
using namespace std;

void foo(bool &keep_run){
    cout << "Inside the thread: Interrupt flag = " << keep_run << endl;
    if (std::cin.get() == 'q') {
        keep_run = false;
        cout << "User Interrupted the process. Interrupt flag = " << keep_run << endl;
    }
}

class VideoCaptureAsync
{
private:
    VideoCapture cam;
    thread th;
    bool read_lock;
    Mat frame;
    Mat grabbed;
    bool isStarted;
public:
    void initiate(unsigned int camId,unsigned int width,unsigned int height,double fps);
    void start();       // a start function to create and start the thread
    void update();      // an update function that will be called asynchronously
    tuple<Mat,Mat> read();        // a read function that we will call from our code to retrieve a new frame.
    void stop();        // a stop function to stop (join) the thread
    void exit();        // an __exit__ function to clean up some resources.
};

void VideoCaptureAsync::initiate(unsigned int camId,double fps){
    cout << "Inside initiate function" << endl;
    cam.open(camId);
    if (!cam.isOpened())
    {
        cerr  << "Could not open the VideoCapture camera: " << camId << endl;
    }
    cam.set(CV_CAP_PROP_FRAME_WIDTH,width);
    cam.set(CV_CAP_PROP_FRAME_HEIGHT,height);
    cam.set(CAP_PROP_FPS,fps);

    isStarted = false;
    read_lock = false;
    VideoCaptureAsync::start();
}

void VideoCaptureAsync::start(){
    cout << "Inside start function" << endl;
    if (isStarted) {
        cout << "Asynchroneous video capturing has already been started" << endl;
    }
    isStarted = true; 
    thread th(&VideoCaptureAsync::update,this);
    //VideoCaptureAsync::update();
}

void VideoCaptureAsync::update(){
    cout << "Inside update function" << endl;
    while(isStarted){
        Mat frame_update;
        Mat grabbed_update;
        tie(frame_update,grabbed_update) = VideoCaptureAsync::read();
        if(!read_lock){
            frame_update.copyTo(frame);
            grabbed_update.copyTo(grabbed);
        }
    }
}

tuple<Mat,Mat> VideoCaptureAsync::read(){
    cout << "Inside read function" << endl;
    if (!read_lock){
        read_lock = true;
        Mat frame_read;
        cam.read(frame_read);
        Mat grabbed_read;
        read_lock = false;
        return make_tuple(frame_read,grabbed_read);
    }
}

void VideoCaptureAsync::stop(){
    cout << "Inside stop function" << endl;
    th.join();
    isStarted = false;
    read_lock = true;
}

void VideoCaptureAsync::exit(){
    cout << "Finished writing ..." << endl;
    cam.release();
}

int main(int argc,char *argv[]){

    const unsigned int camId = 1;
    const bool enableOutput = true;
    const unsigned int w = 1280;
    const unsigned int h = 720;
    double fps = 30.0;


    VideoCaptureAsync obj;
    obj.initiate(camId,w,h,fps);
    bool keep_running = true;
    thread th1(foo,std::ref(keep_running));
    Mat original_frame;

    while (keep_running) {
        std::tie(std::ignore,original_frame) = obj.read();

        if (enableOutput) {
            imshow("Retrieved Image",original_frame);
            waitKey(1000/fps);
        }
    }

    obj.stop();
    obj.exit();

}
woodfishzgw1234 回答:C ++ std :: thread终止被调用而没有活动异常中止

在您的start()方法中:

thread th(&VideoCaptureAsync::update,this);

此语句在start()方法的th方法中创建了一个新的本地对象,这是一个全新的std::thread对象,并以一种创建方式一个新的执行线程。

此后,start()立即返回。这样会破坏该本地对象,调用其析构函数,并导致您的异常。

您的明显意图是使用th类成员来创建新的执行线程,而不是在start()方法中创建新的本地对象。但是上面的C ++语法是一个声明。它声明一个新对象,并在函数中使用时创建一个新的本地对象(在自动作用域中),该对象在作用域末端自动销毁。这就是C ++的工作方式。

为了使新的执行线程从您现有的类成员启动:

th=thread{&VideoCaptureAsync::update,this};

(使用现代C ++的统一初始化语法)。有关更多信息,请参见“ Delayed start of thread in C++11”。

本文链接:https://www.f2er.com/3127048.html

大家都在问