boost::asio::experimental::co_composed lambda函数可以捕获这个指针吗?

问题描述 投票:0回答:1

我已阅读此问答。 C++20 协程的 Lambda 生命周期解释

如果我理解正确的话,如果 lambda 表达式用作协程函数,则捕获某些内容的 lambda 表达式是不安全的。

现在我提出以下问题。

#include <iostream>
#include <boost/asio.hpp>
#include <boost/asio/experimental/co_composed.hpp>

namespace asio = boost::asio;

struct foo {
    template <typename CompletionToken>
    auto mf1(
        CompletionToken&& token
    ) {
        return asio::async_initiate<
            CompletionToken,
            void()
        >(
            asio::experimental::co_composed<
                void()
            >(
                [](                 // capture nothing
                    auto /*state*/,
                    foo& self
                ) -> void {
                    // co_await some_async_function(asio::deferred);
                    self.val_++;    // accesses member variables via self
                    co_return {};
                }
            ),
            token,
            std::ref(*this)
        );
    }

    template <typename CompletionToken>
    auto mf2(
        CompletionToken&& token
    ) {
        return asio::async_initiate<
            CompletionToken,
            void()
        >(
            asio::experimental::co_composed<
                void()
            >(
                [this](              // capture this.
                    auto /*state*/
                ) -> void {
                    // co_await some_async_function(asio::deferred);
                    val_++;          // accesses member variables
                    co_return {};
                }
            ),
            token
        );
    }

    int val_ = 0;
};

asio::awaitable<void> proc() {
    foo f;
    co_await f.mf1(asio::deferred);
    co_await f.mf2(asio::deferred);
    std::cout << f.val_ << std::endl;
    co_return;
}

int main() {
    asio::io_context ioc;
    asio::co_spawn(
        ioc.get_executor(),
        proc(),
        asio::detached
    );
    ioc.run();
}

godbolt 链接:https://godbolt.org/z/d7snvYYqb

class

foo
有两个成员函数。两个成员函数都做同样的事情。它们是由
co_composed
实现的异步函数。
mf1()
的 lambda 表达式没有捕获任何内容,并将
*this
作为
self
传递。
val_
通过
self
访问。我认为这是安全的。

mf2()
的 lambda 表达式捕获此指针。
val_
通过该指针访问。安全吗? 在访问
val_
之前,可以放置co_await,这样上下文就可以切换和切换回来。那么这种情况下,捕获的this指针是如何处理的呢? 我怀疑它可能不安全。

c++ boost coroutine asio
1个回答
0
投票

使用参考资料的安全性如何?该引用必须指向预期类型的有效对象。

这种情况什么时候才能停止?当所引用对象的生命周期结束时,或者当该对象因其他原因而失效时(例如,通过移动)。

在您的代码中,两者都不适用。

foo
住在Asio的coro框架中,很稳定。

侧切线:

这里至关重要的是

this
指的是
foo
实例,而不是 lambda。 lambda 实例很可能沿着异步调用链移动,因此不能被认为是稳定的。当您有价值捕获并意外传递对它们的引用时,这可能是相关的。幸运的是,您可能不需要 lambda 中的太多状态,因为
foo
实例基本上

© www.soinside.com 2019 - 2024. All rights reserved.