Skip to content

Commit cfa137e

Browse files
committed
1. 修改第三章措辞
2. 修改第四章对 `std::async` 执行策略的补充,添加 `libstdc++` 的链接。修改增加对微软 PPL 库脚注
1 parent 04e50a9 commit cfa137e

File tree

2 files changed

+15
-12
lines changed

2 files changed

+15
-12
lines changed

md/03共享数据.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -521,7 +521,7 @@ void lock() { // lock the mutex
521521
}
522522
```
523523

524-
必须得是**当前对象拥有互斥量的所有权析构函数才会调用 unlock() 解锁互斥量**。我们的代码因为调用了 `lock` ,所以 `_Owns` 设置为 `true`函数结束的时候会解锁互斥量
524+
必须得是**当前对象拥有互斥量的所有权析构函数才会调用 unlock() 解锁互斥量**。我们的代码因为调用了 `lock` ,所以 `_Owns` 设置为 `true`函数结束对象析构的时候会解锁互斥量
525525

526526
---
527527

md/04同步操作.md

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -387,23 +387,25 @@ int main(){
387387

388388
而我们先前一直没有写明这个参数,是因为 `std::async` 函数模板有两个**重载**,不给出执行策略就是以:`std::launch::async | std::launch::deferred` 调用另一个重载版本(这一点中在[源码](https://github.com/microsoft/STL/blob/f54203f/stl/inc/future#L1425-L1430)中很明显),此策略表示由实现选择到底是否创建线程执行异步任务。典型情况是,如果系统资源充足,并且异步任务的执行不会导致性能问题,那么系统可能会选择在新线程中执行任务。但是,如果系统资源有限,或者延迟执行可以提高性能或节省资源,那么系统可能会选择延迟执行。
389389

390+
> 如果你阅读 [`libstdc++`](https://github.com/gcc-mirror/gcc/blob/bcb9dad/libstdc%2B%2B-v3/include/std/future#L1818-L1819) 的代码,会发现的确如此。
391+
>
390392
> 然而值得注意的是,在 MSVC STL 的实现中,`launch::async | launch::deferred``launch::async` 执行策略毫无区别,[**源码**](https://github.com/microsoft/STL/blob/f54203f/stl/inc/future#L1400-L1410)如下:
391393
>
392394
> ```cpp
393395
> template <class _Ret, class _Fty>
394396
> _Associated_state<typename _P_arg_type<_Ret>::type>* _Get_associated_state(launch _Psync, _Fty&& _Fnarg) {
395-
> // construct associated asynchronous state object for the launch type
396-
> switch (_Psync) { // select launch type
397-
> case launch::deferred:
398-
> return new _Deferred_async_state<_Ret>(_STD forward<_Fty>(_Fnarg));
399-
> case launch::async: // TRANSITION, fixed in vMajorNext, should create a new thread here
400-
> default:
401-
> return new _Task_async_state<_Ret>(_STD forward<_Fty>(_Fnarg));
402-
> }
397+
> // construct associated asynchronous state object for the launch type
398+
> switch (_Psync) { // select launch type
399+
> case launch::deferred:
400+
> return new _Deferred_async_state<_Ret>(_STD forward<_Fty>(_Fnarg));
401+
> case launch::async: // TRANSITION, fixed in vMajorNext, should create a new thread here
402+
> default:
403+
> return new _Task_async_state<_Ret>(_STD forward<_Fty>(_Fnarg));
404+
> }
403405
> }
404406
> ```
405407
>
406-
> 且 `_Task_async_state` 会通过 [`::Concurrency::create_task`](https://github.com/microsoft/STL/blob/f54203f/stl/inc/future#L663-L665) 从线程池中获取线程并执行任务返回包装对象。
408+
> 且 `_Task_async_state` 会通过 [`::Concurrency::create_task`](https://github.com/microsoft/STL/blob/f54203f/stl/inc/future#L663-L665)[^1] 从线程池中获取线程并执行任务返回包装对象。
407409
>
408410
> 简而言之,使用 `std::async`,只要不是 `launch::deferred` 策略,那么 MSVC STL 实现中都是必然在线程中执行任务。因为是线程池,所以执行新任务是否创建新线程,任务执行完毕线程是否立即销毁,***不确定***。
409411
@@ -447,6 +449,7 @@ int main(){
447449
```
448450
449451
如同没有线程资源所有权的 `std::thread` 对象调用 `join()` 一样错误,这是移动语义的基本语义逻辑。
452+
[^1]: 此设施来自微软[并行模式库](https://learn.microsoft.com/zh-cn/cpp/parallel/concrt/parallel-patterns-library-ppl?view=msvc-170)(PPL),它返回一个 task 类型,它的使用同样可参见[文档](https://learn.microsoft.com/zh-cn/cpp/parallel/concrt/task-parallelism-concurrency-runtime?view=msvc-170#task-class)。不过这不是我们的重点。
450453
451454
### `future``std::packaged_task`
452455
@@ -819,7 +822,7 @@ int main() {
819822
}
820823
```
821824
822-
这样访问的就都是 `std::shared_future` 的副本了,我们的 lambda 按复制捕获 std::shared_future 对象,每个线程都有一个 shared_future 的副本,这样不会有任何问题。这一点和 `std::shared_ptr` 类似[^1]
825+
这样访问的就都是 `std::shared_future` 的副本了,我们的 lambda 按复制捕获 std::shared_future 对象,每个线程都有一个 shared_future 的副本,这样不会有任何问题。这一点和 `std::shared_ptr` 类似[^2]
823826
824827
`std::promise` 也同,它的 `get_future()` 成员函数一样可以用来构造 `std::shared_future`,虽然它的返回类型是 `std::future`,不过不影响,这是因为 `std::shared_future` 有一个 `std::future<T>&&` 参数的[构造函数](https://zh.cppreference.com/w/cpp/thread/shared_future/shared_future),转移 `std::future` 的所有权。
825828
@@ -830,7 +833,7 @@ std::shared_future<std::string>sf{ p.get_future() }; // 隐式转移所有权
830833
831834
就不需要再强调了。
832835
833-
[^1]:注:多个线程能在不同的 shared_ptr 对象上调用所有成员函数(包含复制构造函数与复制赋值)而不附加同步,即使这些实例是同一对象的副本且共享所有权也是如此。若多个执行线程访问同一 shared_ptr 对象而不同步,且任一线程使用 shared_ptr 的非 const 成员函数,则将出现数据竞争;`std::atomic<shared_ptr>` 能用于避免数据竞争。[文档](https://zh.cppreference.com/w/cpp/memory/shared_ptr#:~:text=%E5%A4%9A%E4%B8%AA%E7%BA%BF%E7%A8%8B%E8%83%BD%E5%9C%A8%E4%B8%8D%E5%90%8C%E7%9A%84%20shared_ptr%20%E5%AF%B9%E8%B1%A1%E4%B8%8A%E8%B0%83%E7%94%A8%E6%89%80%E6%9C%89%E6%88%90%E5%91%98%E5%87%BD%E6%95%B0%EF%BC%88%E5%8C%85%E5%90%AB%E5%A4%8D%E5%88%B6%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0%E4%B8%8E%E5%A4%8D%E5%88%B6%E8%B5%8B%E5%80%BC%EF%BC%89%E8%80%8C%E4%B8%8D%E9%99%84%E5%8A%A0%E5%90%8C%E6%AD%A5%EF%BC%8C%E5%8D%B3%E4%BD%BF%E8%BF%99%E4%BA%9B%E5%AE%9E%E4%BE%8B%E6%98%AF%E5%90%8C%E4%B8%80%E5%AF%B9%E8%B1%A1%E7%9A%84%E5%89%AF%E6%9C%AC%E4%B8%94%E5%85%B1%E4%BA%AB%E6%89%80%E6%9C%89%E6%9D%83%E4%B9%9F%E6%98%AF%E5%A6%82%E6%AD%A4%E3%80%82%E8%8B%A5%E5%A4%9A%E4%B8%AA%E6%89%A7%E8%A1%8C%E7%BA%BF%E7%A8%8B%E8%AE%BF%E9%97%AE%E5%90%8C%E4%B8%80%20shared_ptr%20%E5%AF%B9%E8%B1%A1%E8%80%8C%E4%B8%8D%E5%90%8C%E6%AD%A5%EF%BC%8C%E4%B8%94%E4%BB%BB%E4%B8%80%E7%BA%BF%E7%A8%8B%E4%BD%BF%E7%94%A8%20shared_ptr%20%E7%9A%84%E9%9D%9E%20const%20%E6%88%90%E5%91%98%E5%87%BD%E6%95%B0%EF%BC%8C%E5%88%99%E5%B0%86%E5%87%BA%E7%8E%B0%E6%95%B0%E6%8D%AE%E7%AB%9E%E4%BA%89%EF%BC%9Bstd%3A%3Aatomic%3Cshared_ptr%3E%20%E8%83%BD%E7%94%A8%E4%BA%8E%E9%81%BF%E5%85%8D%E6%95%B0%E6%8D%AE%E7%AB%9E%E4%BA%89%E3%80%82)。
836+
[^2]:注:多个线程能在不同的 shared_ptr 对象上调用所有成员函数(包含复制构造函数与复制赋值)而不附加同步,即使这些实例是同一对象的副本且共享所有权也是如此。若多个执行线程访问同一 shared_ptr 对象而不同步,且任一线程使用 shared_ptr 的非 const 成员函数,则将出现数据竞争;`std::atomic<shared_ptr>` 能用于避免数据竞争。[文档](https://zh.cppreference.com/w/cpp/memory/shared_ptr#:~:text=%E5%A4%9A%E4%B8%AA%E7%BA%BF%E7%A8%8B%E8%83%BD%E5%9C%A8%E4%B8%8D%E5%90%8C%E7%9A%84%20shared_ptr%20%E5%AF%B9%E8%B1%A1%E4%B8%8A%E8%B0%83%E7%94%A8%E6%89%80%E6%9C%89%E6%88%90%E5%91%98%E5%87%BD%E6%95%B0%EF%BC%88%E5%8C%85%E5%90%AB%E5%A4%8D%E5%88%B6%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0%E4%B8%8E%E5%A4%8D%E5%88%B6%E8%B5%8B%E5%80%BC%EF%BC%89%E8%80%8C%E4%B8%8D%E9%99%84%E5%8A%A0%E5%90%8C%E6%AD%A5%EF%BC%8C%E5%8D%B3%E4%BD%BF%E8%BF%99%E4%BA%9B%E5%AE%9E%E4%BE%8B%E6%98%AF%E5%90%8C%E4%B8%80%E5%AF%B9%E8%B1%A1%E7%9A%84%E5%89%AF%E6%9C%AC%E4%B8%94%E5%85%B1%E4%BA%AB%E6%89%80%E6%9C%89%E6%9D%83%E4%B9%9F%E6%98%AF%E5%A6%82%E6%AD%A4%E3%80%82%E8%8B%A5%E5%A4%9A%E4%B8%AA%E6%89%A7%E8%A1%8C%E7%BA%BF%E7%A8%8B%E8%AE%BF%E9%97%AE%E5%90%8C%E4%B8%80%20shared_ptr%20%E5%AF%B9%E8%B1%A1%E8%80%8C%E4%B8%8D%E5%90%8C%E6%AD%A5%EF%BC%8C%E4%B8%94%E4%BB%BB%E4%B8%80%E7%BA%BF%E7%A8%8B%E4%BD%BF%E7%94%A8%20shared_ptr%20%E7%9A%84%E9%9D%9E%20const%20%E6%88%90%E5%91%98%E5%87%BD%E6%95%B0%EF%BC%8C%E5%88%99%E5%B0%86%E5%87%BA%E7%8E%B0%E6%95%B0%E6%8D%AE%E7%AB%9E%E4%BA%89%EF%BC%9Bstd%3A%3Aatomic%3Cshared_ptr%3E%20%E8%83%BD%E7%94%A8%E4%BA%8E%E9%81%BF%E5%85%8D%E6%95%B0%E6%8D%AE%E7%AB%9E%E4%BA%89%E3%80%82)。
834837
835838
## 限时等待
836839

0 commit comments

Comments
 (0)