什么是在linux上cQt中解雇和忘记线程的最简单方法?

什么是在linux上cQt中解雇和忘记线程的最简单方法?,第1张

概述我正在编写一个嵌入多个使用Qt同时运行的libVlc实例的应用程序. vlc库中似乎存在一个错误,如果从Qt的GUI线程调用,有时libvlc_media_player_stop会死锁.在其中一个videolan论坛上,接受的解决方案是从另一个线程调用stop函数.我正在寻找最少参与且不太难看的方法来从不同的线程调用stop.我看着使用QThreadPool,这意味着完全适用于这种情况,但在我的特 我正在编写一个嵌入多个使用Qt同时运行的libVlc实例的应用程序. vlc库中似乎存在一个错误,如果从Qt的GUI线程调用,有时libvlc_media_player_stop会死锁.在其中一个vIDeolan论坛上,接受的解决方案是从另一个线程调用stop函数.我正在寻找最少参与且不太难看的方法来从不同的线程调用stop.我看着使用QThreadPool,这意味着完全适用于这种情况,但在我的特殊情况下,它并没有使解决方案很好.

这是我的一段代码:

VlcWidget.h

class VlcWidget : public QWidget    {        Q_OBJECT    private:        // State        bool _isPlaying;        // The streaming source,Title and quality data        VIDeoData _vIDeoData;        VIDEO_QUAliTY _quality;        // libVlc related members        libvlc_instance_t *_vlcInstance;        libvlc_media_player_t *_vlcmediaPlayer;        libvlc_media_t *_vlcmedia;        int _vlcTrackID;    }

VlcWidget.c

voID VlcWidget::Play()    {        if(_vIDeoData.source() != "" && !_isPlaying)        {            // Create a new media descriptor            _vlcmedia = libvlc_media_new_location(                          _vlcInstance,_vIDeoData.source().toStdString().c_str());            // Tell the user about incorrect URL            if(_vlcmedia == NulL)            {                QMessageBox::information(this,_vIDeoData.Title(),"Unable to open source Url.\nPlease check the source and try again.");                return;            }            libvlc_media_player_set_media(_vlcmediaPlayer,_vlcmedia);            libvlc_media_release(_vlcmedia);            libvlc_media_player_set_xwindow(_vlcmediaPlayer,parentWidget()->winID());            libvlc_media_player_play(_vlcmediaPlayer);            _vlcTrackID = libvlc_audio_get_track(_vlcmediaPlayer);            _isPlaying = true;        }    }    voID VlcWidget::Stop()    {        if(_isPlaying)        {            libvlc_media_player_stop(_vlcmediaPlayer);            _vlcTrackID = -1;            _isPlaying = false;        }    }

我使用QthreadPool的解决方案看起来像:

class AsyncVlcPlay : public QRunnable    {    private:         // State        bool *_isPlaying;        // libVlc related members        libvlc_instance_t *_vlcInstance;        libvlc_media_player_t *_vlcmediaPlayer;        libvlc_media_t *_vlcmedia;        int *_vlcTrackID;    public:        virtual voID run();    }

并且AsyncVlcPlay :: run()与VlcWidget :: Play()完全相同,并添加了简单锁定.而且我还需要一个类似VlcWidget :: Stop()的类.我不喜欢这个解决方案,因为我不应该为我想要实现的目标真正需要2个新类.更糟糕的是,我必须将VlcWidgets私有成员传递给另一个类的对象.我很确定这是一种非常简单的方式,我不知道,并希望你们中的一个人可以帮助我.谢谢!

(事实上​​,我真的不需要VlcWidget :: Play()在另一个线程上,但我想保持Play和Stop对称)

解决方法 这是我的(部分)代码,用于将SWI-Prolog语法高亮显示耦合到Qt

// start highlighting,using SWI-Prolog Syntax analyzer to collect structured data//voID pqSource::startHighliter() {    auto f = [](QString file,pqSyntaxData* psd) {        SwiPrologEngine::in_thread _it;        try {            // ?? PlCall("consult",V(A(file)));            qDeBUG() << "running Syntax color on" << file << "thread" << CT;            int rc = PlCall("syncol",pltermv(A(file),plterm(psd)));            qDeBUG() << "syncol" << rc;        }        catch(PlException e) {            qDeBUG() << t2w(e);        }    };    // collect structure asyncronously    auto w = new QFutureWatcher<voID>;    connect(w,SIGNAL(finished()),this,SLOT(runHighliter()));    // since Could be a slow task,place a visual hint to what's going on...    CenterWidgets((sd = new pqSyntaxData)->pgb = new QProgressbar(this));    QTextCursor c = textCursor();    c.moveposition(c.End);    sd->pgb->setMaximum(c.position());    connect(sd,SIGNAL(onProgress(int)),sd->pgb,SLOT(setValue(int)));    sd->pgb->show();    // run the Prolog snippet in background (hl pointer)    w->setFuture(QtConcurrent::run(f,file,sd));}

我想你可能对lambda的使用感兴趣…

总结

以上是内存溢出为你收集整理的什么是在linux上c / Qt中解雇忘记线程的最简单方法?全部内容,希望文章能够帮你解决什么是在linux上c / Qt中解雇和忘记线程的最简单方法?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/1029530.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-23
下一篇 2022-05-23

发表评论

登录后才能评论

评论列表(0条)

保存