简体   繁体   English

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

[英]Is it safe to use boost::asio::strand in this way?

Said I have a worker class 说我有一个工人阶级

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_;
};

Anyone can post works to a worker object, and it will be en-queued and do work in sequence. 任何人都可以将作品发布到工作者对象,它将被排队并按顺序工作。 When I want to stop a worker object, I can just un-reference shared _ptr. 当我想要停止一个worker对象时,我可以取消引用shared _ptr。 Pending work will not call into object (protected by weak_ptr) 待处理的工作不会调用对象(受weak_ptr保护)

Here is example scenario 这是示例场景

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;
}

This exmaple can run without crash. 这个例子可以在没有崩溃的情况下运行。 The output is 输出是

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

No "work 1 done", "work 2 done" which is expected. 没有“工作1完成”,“工作2完成”这是预期的。

But at the time I called io_service::run(), strand is already destroyed. 但是在我调用io_service :: run()时,strand已经被销毁了。 Is this safe? 这样安全吗? Or something undefined behavior may happened? 或者可能发生一些未定义的行为?

Oh, I almost forgot about this question since my comment: 哦,自从我的评论以来,我差点忘了这个问题:

Looks fine to me (much easier to see if you imagine MyWorker::Work as a free function). 对我来说很好看(如果你想象MyWorker :: Work作为免费功能,会更容易看到)。 It does assume that it's okay to have wrapped handlers even after the strand object is destroyed. 它确实假设即使在strand对象被销毁之后也可以包装处理程序。 I think that is okay, but I'd need to check. 我认为没关系,但我需要检查一下。

I did have a look at the implementation and indeed the implementation of the strand service is such that it is safe to have handlers associated with them after destructing the strand instance. 我确实看过了实现,实际上,strand服务的实现是这样的,即在破坏strand实例之后让处理程序与它们相关联是安全的。

That makes your code fine. 这使你的代码很好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM