c++ - 等待异步方法完成

标签 c++ boost-asio

在我的多线程程序中,我经常使用如下所示的方法来同步对数据的访问:

class MyAsyncClass
{

public:     // public thread safe interface of MyAsyncClass

    void start()
    {
        // add work to io_service
        _ioServiceWork.reset(new boost::asio::io_service::work(_ioService));

        // start io service
        _ioServiceThread = boost::shared_ptr<boost::thread>(new boost::thread(boost::bind(&boost::asio::io_service::run, &_ioService)));
    }

    void stop()
    {
        _ioService.post(boost::bind(&MyAsyncClass::stop_internal, this));

        // QUESTION:
        // how do I wait for stop_internal to finish here?

        // remove work
        _ioServiceWork.reset();

        // wait for the io_service to return from run()
        if (_ioServiceThread && _ioServiceThread->joinable())
            _ioServiceThread->join();

        // allow subsequent calls to run()
        _ioService.reset();

        // delete thread
        _ioServiceThread.reset();
    }

    void doSometing()
    {
        _ioService.post(boost::bind(&MyAsyncClass::doSometing_internal, this));
    }

private:        // internal handlers

    void stop_internal()
    {
        _myMember = 0;
    }

    void doSomething_internal()
    {
        _myMember++;
    }

private:        // private variables

    // io service and its thread
    boost::asio::io_service _ioService;
    boost::shared_ptr<boost::thread> _ioServiceThread;

    // work object to prevent io service from running out of work
    std::unique_ptr<boost::asio::io_service::work> _ioServiceWork;

    // some member that should be modified only from _ioServiceThread
    int _myMember;

};

这个类的公共(public)接口(interface)是线程安全的,因为它的公共(public)方法可以从任何线程调用,boost::asio::io_service 负责访问私有(private)成员这个类是同步的。因此,public doSomething() 除了将实际工作发布到 io_service 之外什么都不做。

MyAsyncClassstart()stop() 方法显然在MyAsyncClass 中开始和停止处理。我希望能够从任何线程调用 MyAsyncClass::stop() 并且它不应在 MyAsyncClass 的未初始化完成之前返回。

由于在这种特殊情况下我需要在停止时修改我的一个私有(private)成员(需要同步访问),我引入了一个 stop_internal() 方法,我将其发布到 io_service 来自 stop()

现在的问题是:如何在 stop() 中等待 stop_internal() 的执行完成?请注意,我不能直接调用 stop_internal(),因为它会在错误的线程中运行。

编辑:

如果 MyAsyncClass::stop() 是从 _ioServiceThread 调用的,那么最好有一个解决方案,这样 MyAsyncClass 也可以自行停止。

最佳答案

我刚刚自己找到了一个非常好的解决方案:

我没有在 stop() 中删除工作(重置 _ioServiceWork),而是在 stop_internal() 结束时执行此操作。这意味着 _ioServiceThread->join() 会阻塞,直到 stop_internal() 完成 - 这正是我想要的。

这个解决方案的优点在于它不需要任何互斥量或条件变量或类似的东西。

关于c++ - 等待异步方法完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22665677/

相关文章:

c++ - 创建一个唯一的临时目录

c++ - 关于 boost::asio 套接字和阻塞

c++ - Win32 : Changing Program Icon

C++:定时回调后的WHILE循环会阻止回调吗?

c++ - boost tcp 客户端和服务器之间的 Asio 同步

c++ - boost::asio::deadline_timer 导致 "a function call cannot appear in a constant-expression"错误

c++ - 将 boost::asio::post 用于接受参数的函数

c++ - 找到时替换字符串 vector 中的特定字符 C++

c++ - XCode 中忽略了段错误

c++ - 将 std::unique_ptr 与 std::istream 一起使用?