首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在std::thread中正确嵌入QEventLoop?

如何在std::thread中正确嵌入QEventLoop?
EN

Stack Overflow用户
提问于 2017-11-22 18:46:52
回答 2查看 798关注 0票数 2

有一个包含std::thread的对象,我希望在销毁该对象时完成该对象。

最小工作代码:

代码语言:javascript
复制
#include <thread>
#include <future>
#include <QEventLoop>

struct Connector
{
    Connector(std::string addr, std::function<void(std::string)> cb)
    {
        std::promise<void> barrier;
        auto fut = barrier.get_future();

        m_worker = std::thread([addr, cb, &barrier]()
        {
            QEventLoop loop;
            QTimer::singleShot(0, [this, &barrier, &loop]
            {
                m_quit = [&loop] { QTimer::singleShot(0, &loop, &QEventLoop::quit); };
                barrier.set_value();
            });

            MySocket s(addr, cb);

            loop.exec();
        });

        fut.wait();
    }

    ~Connector()
    {
        m_quit();
        m_worker.join();
    }

    std::thread worker;
    std::function<void()> m_quit;
};

它很快变得复杂起来:您只能在loop进入exec()之后调用exit(),您不能在线程外部创建loop

我只有一个解决方案,其中的信号量是由在此循环中排队等待执行的处理程序释放的。当信号量被释放时,我可以确保循环已经创建并正在运行,因此可以在需要时使用quit()消息终止它。

我是不是错过了一种更简单的方式?

EN

回答 2

Stack Overflow用户

发布于 2017-11-22 19:51:56

也许你可以向线程传递一个对QEventLoop的出口的引用,并在销毁时在该指针上调用unique_ptr。如下所示:

代码语言:javascript
复制
#include <thread>
#include <QEventLoop>

struct Connector
{
    Connector()
    {
        m_worker = std::thread([=]()
        {
            event_loop = std::make_unique<QEventLoop>();
            loop->exec();
        });
    }

    ~Connector()
    {
        event_loop->exit();
        m_worker.join();
    }

    std::unique_ptr<QEventLoop> event_loop;
    std::thread worker;
};
票数 0
EN

Stack Overflow用户

发布于 2017-11-22 21:28:06

以下是我对此的看法,基于katrasnikj的回答和std::promise docs,以确保在构造函数完成时线程正在运行。

代码语言:javascript
复制
struct Connector
{
    Connector()
    {
        std::promise<void> barrier;
        auto fut = barrier.get_future();
        worker = std::thread([=](std::promise<void>&& barrier)
        {
            event_loop = std::make_unique<QEventLoop>();
            barrier.set_value();
            event_loop->exec();
        }, std::move(barrier));
        fut.wait();
    }

    ~Connector()
    {
        QTimer::singleShot(0, event_loop.get(), &QEventLoop::quit);
        worker.join();
    }

    std::unique_ptr<QEventLoop> event_loop;
    std::thread worker;
};

但您可能会考虑使用QThread,因为它能够运行自己的事件循环。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47432720

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档