Update item39.md

This commit is contained in:
猫耳堀川雷鼓 2021-03-13 21:54:25 +08:00 committed by GitHub
parent cbedd8c646
commit 70d4cb313e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -175,7 +175,7 @@ void detect()
这样看起来安全多了。问题在于第一个“…”区域中(注释了“`tr`中的线程在这里被挂起”的那句),如果异常发生,`p`上的`set_value`永远不会调用,这意味着*lambda*中的`wait`永远不会返回。那意味着在*lambda*中运行的线程不会结束这是个问题因为RAII对象`tr`在析构函数中被设置为在(`tr`中创建的)那个线程上实行`join`。换句话说,如果在第一个“…”区域中发生了异常,函数挂起,因为`tr`的析构函数永远无法完成。
有很多方案解决这个问题,但是我把这个经验留给读者。(一个开始研究这个问题的好地方是我的博客*[The View From Aristeia](http://scottmeyers.blogspot.com/)*2013年12月24日的文章“[ThreadRAII + Thread Suspension = Trouble?](http://scottmeyers.blogspot.com/2013/12/threadraii-thread-suspension-trouble.html)”这里我只想展示如何扩展原始代码即不使用RAII类使其挂起然后取消挂起不仅一个反应任务而是多个任务。简单概括关键就是在`react`的代码中使用`std::shared_future`代替`std::future`。一旦你知道`std::future`的`share`成员函数将共享状态所有权转移到`share`产生的`std::shared_future`中,代码自然就写出来了。唯一需要注意的是,每个反应线程都需要自己的`std::shared_future`副本,该副本引用共享状态,因此通过`share`获得的`shared_future`要被在反应线程中运行的*lambda*按值捕获:
有很多方案解决这个问题,但是我把这个经验留给读者。(一个开始研究这个问题的好地方是我的博客[*The View From Aristeia*](http://scottmeyers.blogspot.com/)中2013年12月24日的文章“[ThreadRAII + Thread Suspension = Trouble?](http://scottmeyers.blogspot.com/2013/12/threadraii-thread-suspension-trouble.html)”这里我只想展示如何扩展原始代码即不使用RAII类使其挂起然后取消挂起不仅一个反应任务而是多个任务。简单概括关键就是在`react`的代码中使用`std::shared_future`代替`std::future`。一旦你知道`std::future`的`share`成员函数将共享状态所有权转移到`share`产生的`std::shared_future`中,代码自然就写出来了。唯一需要注意的是,每个反应线程都需要自己的`std::shared_future`副本,该副本引用共享状态,因此通过`share`获得的`shared_future`要被在反应线程中运行的*lambda*按值捕获:
```cpp
std::promise<void> p; //跟之前一样