简体   繁体   中英

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. Pending work will not call into object (protected by 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.

But at the time I called io_service::run(), strand is already destroyed. 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). It does assume that it's okay to have wrapped handlers even after the strand object is destroyed. 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.

That makes your code fine.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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