【问题标题】:Block execution program until callback function complete execution阻塞执行程序,直到回调函数完成执行
【发布时间】:2019-04-29 09:44:19
【问题描述】:

如何阻止程序执行直到回调函数完成执行?

从我的 main() 我启动 interface.getImage();想要从我们的数据库中获取图像的函数。当我们接收到图像时,回调函数 void InterfaceColliseo::dataReceived (std::shared_ptr data) 开始执行。 但是我有一个问题,我的程序 main() 在我的回调函数执行之前终止了?

ma​​in.cpp

int main(){
        InterfaceColliseo interface;
        IMAGE = true;
        interface.getImage();

        // want to block program here
        return 0;
}


回调函数

void InterfaceColliseo::dataReceived (std::shared_ptr<IData> data)
{
    if (!data->isValid())
        return;

    const unsigned char* twoDImageData = data->get2DImageData();
    int width2DImageData = data->getWidth2DImageData();
    int height2DImageData = data->getHeight2DImageData();
    const unsigned char* disparityData = data->getDisparityData();
    int widthDisparityData = data->getWidthDisparityData();
    int heightDisparityData = data->getHeightDisparityData();

    if(IMAGE) {
        saveImage(twoDImageData, width2DImageData, height2DImageData,
                  disparityData, widthDisparityData, heightDisparityData);
        IMAGE = false;
    }

    if(ACQUISATION){
        QList<GstObservationBasic> detectorData = data->getObstaclesData();
        getObstacles(detectorData);

    }

}

【问题讨论】:

    标签: c++ qt


    【解决方案1】:

    我认为你可以使用 std 中的线程。当你使用join时,主线程会一直等待直到joined线程完成他的工作。

    #include <thread>
    
    //in main
    std::thread myThread(interface.getImage);
    myThread.join();
    

    【讨论】:

    • 这无济于事,myThread 将在调用interface.getImage() 之后完成其工作,这不会阻塞。
    • @Annyo 好吧,你可能是对的!我不知道 getImage 实现是什么方法以及如何(以及在​​哪里)调用 dataReceived
    • @Raffallo 我喜欢阻止执行直到回调完成而不是 interface.getImage() 函数。我使用 condition_variable extern std::mutex mtx; extern std::condition_variable cv;
    • dataReceived 是一个回调函数,在从数据库中恢复图像后调用。
    • @Kamel-GH 你能给我们InterfaceColliseo的代码吗?
    【解决方案2】:
    #include "interface_colliseo.h"
    
    std::mutex mtx;
    std::condition_variable cv;
    
    
    bool IMAGE;
    bool ACQUISATION;
    
    InterfaceColliseo::InterfaceColliseo(){
    }
    
    void InterfaceColliseo::startStreaming(){
        dataReceiver = _device->getDataReceiver();
        start();
    
    }
    
    void InterfaceColliseo::getImage(){
        dataReceiver = _device->getDataReceiver();
        start();
    }
    
    InterfaceColliseo::InterfaceColliseo(QString IP): _IP(IP) {
        qDebug() << "INDUS-5: IP server: " << _IP;
        qDebug() << "INDUS-5: Connecting to sensor...";
        _colliseoClient.setIPServer(_IP);
    
    }
    
    bool InterfaceColliseo::connect2UT(){
        QString path = qApp->applicationDirPath()+"/Configuration.ini";
        QSettings config(path, QSettings::IniFormat);
        _IP = config.value("Connection/IP","10.0.3.144").toString();
    
        _colliseoClient.setIPServer(_IP);
        _device = _colliseoClient.getDevice();
        _device->connectSensor();
        bool connect = _device->isConnected();
        return connect;
    }
    
    QString InterfaceColliseo::sensorName(){
        return _device->getDeviceDiagnostics()->getOperatingData()
                ->getDeviceInformation()->getOrderNumber();
    }
    
    QString InterfaceColliseo::sensorFirmwareVersion(){
        return _device->getDeviceDiagnostics()->getOperatingData()
               ->getDeviceInformation()->getFirmwareVersion();
    }
    
    QString InterfaceColliseo::getSensorHeadPN(QString sensor){
         return _device->getDeviceDiagnostics()->getOperatingData()
                 ->getDeviceInformation()->getSensorHeadPN(sensor);
    }
    
    QString InterfaceColliseo::getEvaluationUnitSN(){
        return _device->getDeviceDiagnostics()->getOperatingData()
                ->getDeviceInformation()->getEvaluationUnitSN();
    }
    
    QString InterfaceColliseo::getEvaluationUnitPN(){
        return _device->getDeviceDiagnostics()->getOperatingData()
                ->getDeviceInformation()->getEvaluationUnitPN();
    }
    
    QString InterfaceColliseo::getEvaluationUnitFirmwareVersion(){
        return _device->getDeviceDiagnostics()->getOperatingData()
                ->getDeviceInformation()->getEvaluationUnitFirmwareVersion();
    
    }
    
    QString InterfaceColliseo::getEstimatedAngleX(){
        return _device->getDeviceDiagnostics()->getOperatingData()
                ->getDeviceInformation()->getEstimatedAngleX();
    
    }
    
    QString InterfaceColliseo::getEstimatedAngleZ(){
        return _device->getDeviceDiagnostics()->getOperatingData()
                ->getDeviceInformation()->getEstimatedAngleZ();
    
    }
    
    QString InterfaceColliseo::getEstimatedHeight(){
        return _device->getDeviceDiagnostics()->getOperatingData()
                ->getDeviceInformation()->getEstimatedHeight();
    
    }
    
    void InterfaceColliseo::saveImage(const unsigned char*twoDImageData,
                                      int width2DImageData, int height2DImageData,
                                      const unsigned char*disparityData,
                                      int widthDisparityData, int disptHeight){
        Configuration configuration;
    
        QString logFolder = configuration.getLogFolder();
    
        QImage imgRight(twoDImageData, width2DImageData, height2DImageData, QImage::Format_Indexed8);
        QImage imgDisparity(disparityData, widthDisparityData, disptHeight, QImage::Format_Indexed8);
    
        QPixmap imgRght = QPixmap::fromImage(imgRight);
        QPixmap imgDisp = QPixmap::fromImage(imgDisparity);
    
        QString rghtImgPath = logFolder + "raw_image.png";
        QString dispImgPath = logFolder + "disp_image.png";
    
        imgRght.save(rghtImgPath, "PNG");
        imgDisp.save(dispImgPath, "PNG");
    
    }
    
    
    void InterfaceColliseo::getObstacles(QList<GstObservationBasic> detectorData){
    
        if (detectorData.size() == 0)
        {
            qDebug() << "Obstacles: no detected obstacles.";
            return;
        }
    
        Configuration config;
        config.writeLog("***************Obstacles List Acquisation******************");
        Q_FOREACH(const GstObservationBasic &obs, detectorData)
        {
    
            qDebug() << "Obstacles: " << gstObservationToString(obs);
            config.writeLog(gstObservationToString(obs));
        }
    }
    
    
    void InterfaceColliseo::dataReceived (std::shared_ptr<IData> data)
    {
        if (!data->isValid())
            return;
    
        const unsigned char* twoDImageData = data->get2DImageData();
        int width2DImageData = data->getWidth2DImageData();
        int height2DImageData = data->getHeight2DImageData();
        const unsigned char* disparityData = data->getDisparityData();
        int widthDisparityData = data->getWidthDisparityData();
        int heightDisparityData = data->getHeightDisparityData();
    
        if(IMAGE) {
            saveImage(twoDImageData, width2DImageData, height2DImageData,
                      disparityData, widthDisparityData, heightDisparityData);
            IMAGE = false;
        }
    
        if(ACQUISATION){
            QList<GstObservationBasic> detectorData = data->getObstaclesData();
            getObstacles(detectorData);
            ACQUISATION = false;
    
        }
    
    }
    
    void InterfaceColliseo::start() {
    
        dataReceiver->addListener(this);
    
        if(dataReceiver->isListening())
            dataReceiver->stopListening();
    
        dataReceiver->startListening();
        _device->triggerSingleImageAcquisition();
    }
    

    【讨论】:

    • 如果此代码提供自我回答,请提供一些带有解释的文本。如果这是您问题的额外公开代码,请edit 问题。对我来说,作为minimal reproducible example 的代码似乎太多了。当然可以将其减少到重现您的问题所绝对必要的最低限度,这可能有助于引起对您问题的更多关注。
    猜你喜欢
    • 2015-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多