以这种方式使用boost :: asio :: strand是否安全?

时间:2018-02-08 04:45:30

标签: c++ boost-asio c++17

说我有一个工人阶级

class MyWorker : public std::enable_shared_from_this<MyWorker> {
public:
    MyWorker(boost::asio::io_service& ioService) : strand_(ioService) {}

    void Work(int n) {
        strand_.post([weak_this = weak_from_this(), n]() {
            printf("work %d run from strand\n", n);
            if (auto ptr = weak_this.lock()) ptr->DoWork(n);
        });
    }

    void DoWork(int n) {
        n_ = n;
        printf("work %d done\n", n);
    }

private:
    boost::asio::io_service::strand strand_;
    int n_;
};

任何人都可以将作品发布到工作者对象,它将被排队并按顺序工作。当我想要停止一个worker对象时,我可以取消引用shared _ptr。待处理的工作不会调用对象(受weak_ptr保护)

以下是示例场景

int main() {
    boost::asio::io_service ioService;
    auto worker = std::make_shared<MyWorker>(ioService);

    ioService.post([] () { printf("other work 1\n"); });
    worker->Work(1);
    ioService.post([] () { printf("other work 2\n"); });
    worker->Work(2);

    worker.reset(); // <- strand_ destroyed after this line

    ioService.run();
    return 0;
}

这个例子可以在没有崩溃的情况下运行。输出是

other work 1
work 1 run from strand
other work 2
work 2 run from strand

否&#34;工作1完成&#34;,&#34;工作2完成&#34;这是预期的。

但是在我调用io_service :: run()时,strand已经被销毁了。这样安全吗?或者可能发生一些未定义的行为?

1 个答案:

答案 0 :(得分:1)

哦,自从我发表评论以来,我几乎忘记了这个问题:

  

对我来说很好看(如果你想象MyWorker :: Work作为免费功能,会更容易看到)。它确实假设即使在strand对象被销毁之后也可以包装处理程序。我认为没关系,但我需要检查一下。

我确实看过了实现,实际上,strand服务的实现使得在破坏Sensor A: date value date 2017-11-30 00:00:00 30/11/17 0.00 49 2017-11-30 00:02:00 30/11/17 0.02 51 2017-11-30 00:03:00 30/11/17 0.03 54 2017-11-30 00:05:00 30/11/17 0.05 57 Sensor B: date value date 2017-11-30 00:00:00 30/11/17 0.00 1 2017-11-30 00:02:00 30/11/17 0.02 40 2017-11-30 00:04:00 30/11/17 0.03 11 2017-11-30 00:05:00 30/11/17 0.05 57 AxB date valueA valueB date 2017-11-30 00:00:00 30/11/17 0.00 49 1 2017-11-30 00:02:00 30/11/17 0.02 51 40 2017-11-30 00:03:00 30/11/17 0.03 54 11 2017-11-30 00:05:00 30/11/17 0.05 57 57 实例后让处理程序与它们相关联是安全的。

这使你的代码很好。