【问题标题】:boost asio post not working , io_service::run exits right after postboost asio post 不工作, io_service::run 在 post 后立即退出
【发布时间】:2014-12-17 13:09:54
【问题描述】:

我正在尝试将 boost 信号与 asio 混合以执行基于调度的处理程序调用。当从线程调用 post 方法时,io_service::run 立即退出,处理 post 的回调永远不会被调用,回调是 C++11 lambda 例程。我正在粘贴代码以进行更多分析。

#include<iostream>
#include<thread>
#include<boost/signals2/signal.hpp>
#include<boost/asio.hpp>

static boost::asio::io_service svc;
static boost::signals2::signal<void(std::string)> textEntered;

static void
handleInputText(std::string text)
{
    std::cout<<"handleInputText()"<<" text provided: "<<text;
    return;
}

static void 
worker()
{
    sleep(2);
    svc.post([](){
            std::cout<<"\nRaising signal.";
            std::string hello("hello world");
            textEntered(hello);
            });
    return;
}

int main(int ac, char **av)
{
    try
    {
        textEntered.connect(&handleInputText);
        std::thread w(std::bind(&worker));
        svc.run();
        w.join();
    }
    catch(std::exception &ex)
    {
        std::cerr<<"main() exited with exception:"<<ex.what();
    }
    return 0;
}

【问题讨论】:

    标签: c++11 boost boost-asio


    【解决方案1】:

    您实际上并未向服务发布任何工作。

    您启动了一个可能最终发布工作的线程,但此时主线程已经退出。

    要么在线程上运行 ioservice,要么确保它有 io_service::work

    这是一个使用专用服务线程和 work 项目的修复:

    Live On Coliru

    #include<boost/asio.hpp>
    #include<iostream>
    #include<boost/asio.hpp>
    #include<boost/signals2.hpp>
    #include<boost/thread.hpp>
    #include<boost/make_shared.hpp>
    
    static boost::asio::io_service svc;
    static boost::shared_ptr<boost::asio::io_service::work> work_lock;
    
    static boost::signals2::signal<void(std::string)> textEntered;
    
    static void
    handleInputText(std::string text)
    {
        std::cout<<"handleInputText()"<<" text provided: "<<text;
        return;
    }
    
    static void 
    worker()
    {
        sleep(2);
        svc.post([](){
                std::cout<<"\nRaising signal.";
                std::string hello("hello world");
                textEntered(hello);
           });
        return;
    }
    
    int main()
    {
        try
        {
            work_lock = boost::make_shared<boost::asio::io_service::work>(svc);
            textEntered.connect(&handleInputText);
    
            boost::thread_group tg;
            tg.create_thread(boost::bind(&boost::asio::io_service::run, &svc));
            tg.create_thread(&worker);
    
            boost::this_thread::sleep_for(boost::chrono::seconds(3));
            work_lock.reset();
    
            tg.join_all();
        }
        catch(std::exception &ex)
        {
            std::cerr<<"main() exited with exception:"<<ex.what();
        }
        return 0;
    }
    

    打印:

    Raising signal.handleInputText() text provided: hello world
    

    【讨论】:

    • 在上面的代码中,run 应该阻塞,直到线程发帖。然后有一个连接等待线程。据我了解, run() 永远不应该返回。我只是好奇为什么 run 会在调用 post 的那一刻返回。
    • @RavikumarTulugu 没有。 run() 不应该阻止。阅读文档。不,它不会在调用post 的那一刻返回。它返回。立即地。 (没有理由等待 >2 秒“以防万一有工作到达”)
    • 添加了固定样本,以防万一
    • 文档说,run 是 boost io_service 对象的事件处理循环。事件处理循环永远阻塞,直到我们打破循环。我错过了什么吗?
    • 是的。您错过了中断循环的部分,因为它耗尽了工作(或者,它从来没有任何工作)。文档:The run() function blocks until all work has finished and there are no more handlers to be dispatched, or until the io_service has been stopped。因此,当您启动它时,它会在队列中查找。它注意到队列是空的,所以“所有工作都完成了”。完毕。您在我的回答中看到了解决方法吗?
    猜你喜欢
    • 1970-01-01
    • 2012-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-09
    • 2019-01-22
    • 1970-01-01
    相关资源
    最近更新 更多