我看了这个问题:Is seastar::thread a stackful coroutine?
Botond Dénes在对答案的评论中写道:
说,seastar::线程在后协同世界中仍然有它的(小众)用途,因为它支持在析构函数和catch子句中等待期货,允许使用RAII和更干净的错误处理。这是合作组织不能也不能支持的事情。
有人能详细说明一下吗?当“在析构函数中等待期货”和“catch子句”这样的事情在无堆栈的协同条件下是不可能的,但是在seastar::thread (以及类似的)情况下是可能的呢?
更广泛地说,seastar::thread相对于C++20无堆栈协同线有什么优势?是否所有堆叠的协同实现(例如,在Boost中)都有这些相同的优点?
发布于 2022-06-07 21:17:24
您可能听说过C++中的RAII (资源获取是初始化)成语,它对于确保在出现异常的情况下释放资源非常有用。在经典的同步C++世界中,下面是一个例子:
{
someobject o = get_an_o();
// At this point, "o" is holding some resource (e.g., an open file)
call_some_function(o);
return;
// "o" is destroyed if call_some_function() throws, or before the return.
// When it does, the file it was holding is automatically closed.
} 现在,让我们考虑使用Seastar的异步代码。假设get_an_o()需要一些时间来完成它的工作(例如,打开一个磁盘文件),并返回一个future<someobject>。那么,您可能会认为您可以只使用这样的无堆栈协同:
someobject o = co_await get_an_o();
// At this point, "o" is holding some resource (e.g., an open file)
call_some_function(o);
return;但这里有个问题。虽然someobject构造函数可以是异步的(通过使用工厂函数,get_an_o()in this example), thein this example), thein this example), the function `析构函数仍然是同步的.它在展开堆栈时由C++调用,它不能返回未来!因此,如果对象的析构函数确实需要等待(例如,刷新文件),则不能使用RAII。
使用seastar::thread允许您仍然使用RAII,因为现在的析构函数可以等待。这是因为在seastar::thread中,任何代码--包括析构函数--都可能在将来使用get()。这不会从析构函数返回一个未来(我们不能)-相反,它只是“暂停”堆叠的协同线(切换到其他任务,然后返回到这个堆栈时,当未来解决)。
https://stackoverflow.com/questions/72370073
复制相似问题