c++ - 如何在 Windows 上停止 boost::ioservice

标签 c++ boost boost-asio

找到解决方案
我正在使用 VS2013,boost 1.59.0
我有以下来自 boost c++ application development cookbook
的例子 我在 Windows 上停止 boost::ioservice 时遇到问题。我现在找到了一种解决方法来停止它,即使用 ios_.stopped()

#include <boost/thread/thread.hpp>
#include <boost/asio/io_service.hpp>

namespace detail
{

    template <class T>
    struct task_wrapped
    {
    private:
        T task_unwrapped_;
    public:
        explicit task_wrapped(const T& task_unwrapped)
            : task_unwrapped_(task_unwrapped)
        {}
        void operator()() const
        {
            // resetting interruption
            try
            {
                boost::this_thread::interruption_point();
            }
            catch (const boost::thread_interrupted&){}

            try
            {
                // Executing task
                task_unwrapped_();
            }
            catch (const std::exception& e)
            {
                std::cerr << "Exception: " << e.what() << '\n';
            }
            catch (const boost::thread_interrupted&)
            {
                std::cerr << "Thread interrupted\n";
            }
            catch (...)
            {
                std::cerr << "Unknown exception\n";
            }
        }
    };

    template <class T>
    task_wrapped<T> make_task_wrapped(const T& task_unwrapped)
    {
        return task_wrapped<T>(task_unwrapped);
    }
} // namespace detail

class tasks_processor;
tasks_processor* pProcessor = nullptr;
class tasks_processor : private boost::noncopyable {
    boost::asio::io_service ios_;
    boost::asio::io_service::work work_;
    tasks_processor()
        : ios_()
        , work_(ios_)
    {}
public:
    static tasks_processor& get()
    {
        if (pProcessor == nullptr)
        {
            pProcessor = new tasks_processor;
        }
        return *pProcessor;
    }

    template <class T>
    inline void push_task(const T& task_unwrapped) {
        ios_.post(detail::make_task_wrapped(task_unwrapped));
    }

    void start() {
        ios_.run();
    }
    void stop() {
        ios_.stop();
    }
    bool IsStopped() {
        return ios_.stopped();
    }
}; // tasks_processor

int g_val = 0;
void func_test()
{
    if (tasks_processor::get().IsStopped())
        return;
    ++g_val;
    if (g_val == 3)
    {
        throw std::logic_error("Just checking");
    }
    boost::this_thread::interruption_point();
    if (g_val == 10)
    {
        // Emulation of thread interruption.
        // Will be caught and won't stop execution.
        throw boost::thread_interrupted();
    }
    if (g_val == 90)
    {
        tasks_processor::get().stop();
    }
}


int main()
{
    static const std::size_t tasks_count = 100;
    // stop() is called at 90
    BOOST_STATIC_ASSERT(tasks_count > 90);
    for (std::size_t i = 0; i < tasks_count; ++i)
    {
        tasks_processor::get().push_task(&func_test);
    }

    // We can also use result of boost::bind call
    // as a task
    tasks_processor::get().push_task(
        boost::bind(std::plus<int>(), 2, 2) // counting 2 + 2
        );

    // Processing was not started.
    assert(g_val == 0);
    // Will not throw, but blocks till
    // one of the tasks it is owning
    // calls stop().
    tasks_processor::get().start();
    assert(g_val == 90);
    return 0;
}

问题是变量 g_val 等于 100,这意味着 ios_.stop(); 不工作。我以调试方式运行并且已调用此命令。如何停止 boost::ioservice

最佳答案

io_service::stop() 只是改变 io_service 事件循环的状态,它会导致 io_service::run() 调用尽快返回。没有记录 stop() 是否取消已经排队的处理程序,根据这个 post 看来它取决于操作系统.因此,当 g_val == 90 时,io_service::stop() 被调用,但剩余的 func_test() 可能仍会被执行。

关于c++ - 如何在 Windows 上停止 boost::ioservice,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41905398/

相关文章:

c++ - 如何为指针和动态内存分配定义模板?

c++ - 获取 std::optional 包含的类型的最佳方法是什么?

c++ - 如果您不知道原始类型是有符号的还是无符号的,有没有办法从 boost::any 中获取整数

c++ - boost::共享_??对于非指针资源

c++ - boost::buffer 和 boost::async_write

c++ - 通过代理服务器提升 asio 套接字连接

c++ - 无法在简单程序中按下 QPushButton

c++ - 如何使用 boost::json::value 调用无参数函数

c++ - boost 构建中缺少头文件

c++ - 在套接字关闭之前不发送数据