Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 3078c28

Browse files
committed
1. 修改用词"堵塞"->"阻塞"。
2. 稍微修改线程池一章中的部分描述。Mq-b#12 3. 修改捐赠页面。
1 parent 6eb34a0 commit 3078c28

File tree

4 files changed

+14
-14
lines changed

4 files changed

+14
-14
lines changed

‎README.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828

2929
<div align="center">
3030

31-
![猫猫虫](/image/猫猫虫旋转.jpg)
31+
![猫猫虫](./image/猫猫虫旋转.jpg)
3232

3333
如果你觉得本仓库对你有所帮助,可以通过支付宝赞助白老师,激励白老师有更多的精力和信心维护本仓库。
3434

@@ -37,4 +37,4 @@
3737
> [!TIP]
3838
> 每一位开发者赞助 `30`,白老师一天的食品安全就有了着落。
3939
40-
![赞助](/image/赞助.jpg)
40+
<imgsrc="./image/赞助.jpg"width=512pxalt="cpp"/>

‎md/02使用线程.md‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ int main(){
3636

3737
`std::thread t{ hello };` 创建了一个线程对象 `t`,将 `hello` 作为它的[可调用(Callable)](https://zh.cppreference.com/w/cpp/named_req/Callable)对象,在新线程中执行。线程对象关联了一个线程资源,我们无需手动控制,在线程对象构造成功,就自动在新线程开始执行函数 `hello`
3838

39-
`t.join();` 等待线程对象 `t` 关联的线程执行完毕,否则将一直堵塞。这里的调用是必须的,否则 `std::thread` 的析构函数将调用 [`std::terminate()`](https://zh.cppreference.com/w/cpp/error/terminate) 无法正确析构。
39+
`t.join();` 等待线程对象 `t` 关联的线程执行完毕,否则将一直阻塞。这里的调用是必须的,否则 `std::thread` 的析构函数将调用 [`std::terminate()`](https://zh.cppreference.com/w/cpp/error/terminate) 无法正确析构。
4040

4141
这是因为我们创建线程对象 `t` 的时候就关联了一个活跃的线程,调用 `join()` 就是确保线程对象关联的线程已经执行完毕,然后会修改对象的状态,让 [`std::thread::joinable()`](https://zh.cppreference.com/w/cpp/thread/thread/joinable) 返回 `false`,表示线程对象目前没有关联活跃线程。`std::thread` 的析构函数,正是通过 `joinable()` 判断线程对象目前是否有关联活跃线程,如果为 `true`,那么就当做有关联活跃线程,会调用 `std::terminate()`
4242

@@ -291,7 +291,7 @@ my_thread.join();
291291

292292
认为这样可以确保被分离的线程在这里阻塞执行完?
293293

294-
我们前面聊的很清楚了,detach() 是线程分离,**线程对象放弃了线程资源的所有权**,此时我们的 my_thread 它现在根本没有关联任何线程。调用 join() 是:"阻塞当前线程直至 *this 所标识的线程结束其执行",我们的**线程对象都没有线程,堵塞什么?执行什么呢?**
294+
我们前面聊的很清楚了,detach() 是线程分离,**线程对象放弃了线程资源的所有权**,此时我们的 my_thread 它现在根本没有关联任何线程。调用 join() 是:"阻塞当前线程直至 *this 所标识的线程结束其执行",我们的**线程对象都没有线程,阻塞什么?执行什么呢?**
295295

296296
简单点说,必须是 std::thread 的 joinable() 为 true 即线程对象有活跃线程,才能调用 join() 和 detach()。
297297

@@ -691,7 +691,7 @@ int main() {
691691
}
692692
```
693693
694-
这段代码通过**移动构造**转移了线程对象 `t` 的线程资源所有权到 `t2`,这里虽然有两个 `std::thread` 对象,但是从始至终只有一个线程资源,让持有线程资源的 `t2` 对象最后调用 `join()` 堵塞让其线程执行完毕`t``t2` 都能正常析构。
694+
这段代码通过**移动构造**转移了线程对象 `t` 的线程资源所有权到 `t2`,这里虽然有两个 `std::thread` 对象,但是从始至终只有一个线程资源,让持有线程资源的 `t2` 对象最后调用 `join()` 阻塞让其线程执行完毕`t``t2` 都能正常析构。
695695
696696
我们还可以使用移动赋值来转移线程资源的所有权:
697697

‎md/04同步操作.md‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -446,14 +446,14 @@ int main(){
446446
447447
其实到此基本就差不多了,我们再介绍两个常见问题即可:
448448
449-
1. 如果从 `std::async` 获得的 [std::future](https://zh.cppreference.com/w/cpp/thread/future) 没有被移动或绑定到引用,那么在完整表达式结尾, [std::future](https://zh.cppreference.com/w/cpp/thread/future)**析构函数将阻塞到异步计算完成**。因为临时对象的生存期就在这一行,调用析构函数阻塞执行
449+
1. 如果从 `std::async` 获得的 [`std::future`](https://zh.cppreference.com/w/cpp/thread/future) 没有被移动或绑定到引用,那么在完整表达式结尾, `std::future`**[析构函数](https://zh.cppreference.com/w/cpp/thread/future/%7Efuture)将阻塞,直到到异步任务完成**。因为临时对象的生存期就在这一行,而对象生存期结束就会调用调用析构函数
450450
451451
```cpp
452452
std::async(std::launch::async, []{ f(); }); // 临时量的析构函数等待 f()
453453
std::async(std::launch::async, []{ g(); }); // f() 完成前不开始
454454
```
455455
456-
如你所见,这并不能创建异步任务,会堵塞,然后逐个执行。
456+
如你所见,这并不能创建异步任务,它会阻塞,然后逐个执行。
457457
458458
2. 被移动的 `std::future` 没有所有权,失去共享状态,不能调用 `get`、`wait` 成员函数。
459459
@@ -489,7 +489,7 @@ std::packaged_task<double(int, int)> task([](int a, int b){
489489
});
490490
std::future<double>future = task.get_future();
491491
task(10, 2); // 此处执行任务
492-
std::cout << future.get() << '\n'; // 不堵塞,此处获取返回值
492+
std::cout << future.get() << '\n'; // 不阻塞,此处获取返回值
493493
```
494494
495495
> [运行](https://godbolt.org/z/799Khvadc)测试。
@@ -505,7 +505,7 @@ std::thread t{ std::move(task),10,2 }; // 任务在线程中执行
505505
// todo.. 幻想还有许多耗时的代码
506506
t.join();
507507
508-
std::cout << future.get() << '\n'; // 并不堵塞,获取任务返回值罢了
508+
std::cout << future.get() << '\n'; // 并不阻塞,获取任务返回值罢了
509509
```
510510
511511
> [运行](https://godbolt.org/z/85r9db49z)测试。

‎md/详细分析/04线程池.md‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ graph TD
7272

7373
---
7474

75-
了解以上这些基础概念是第一步也是最后一步,随着水平的提升,对这些概念认知与理解也会逐渐提升
75+
了解以上这些基础概念是第一步也是最后一步,随着水平的提升,对这些概念的理解也会逐渐提升
7676

7777
## 市面上常见的线程池
7878

@@ -169,7 +169,7 @@ for (int i = 0; i < 10; ++i) {
169169

170170
> [运行](https://godbolt.org/z/haPqKb1h7)测试。
171171
172-
因为析构函数并不是堵塞执行完所有任务,而是先**停止**,再 `join()` 以及 `shutdown()`
172+
因为析构函数并不是阻塞直到执行完所有任务,而是先**停止**,再 `join()` 以及 `shutdown()`
173173

174174
`Boost.Asio` 提供的线程池使用十分简单,接口高度封装,几乎无需关心底层具体实现,易于使用。
175175

@@ -450,7 +450,7 @@ int main() {
450450
} // 析构自动 stop() join()
451451
```
452452
453-
**可能的[运行结果](https://godbolt.org/z/YT4ahh1Wz)**:
453+
**可能的[运行结果](https://godbolt.org/z/3rbExqbb7)**:
454454
455455
```shell
456456
Task 0 is running.
@@ -495,11 +495,11 @@ sum: 90
495495

496496
- **`start()`**:启动线程池,创建并启动指定数量的线程。
497497

498-
---
498+
我们并没有提供一个功能强大的所谓的"***调度器***",我们只是利用条件变量和互斥量,让操作系统自行调度而已,它并不具备设置任务优先级之类的调度功能。
499499

500500
当然,你可能还希望我们的线程池具备更多功能或改进,比如控制任务优先级、设置最大线程数量、返回当前活跃线程数等。此外,异常处理也是一个值得考虑的方面。
501501

502-
有些功能实现起来非常简单,而有些则需要更多的思考和设计。不过,这些优化超出了本次讲解的范围。如果有兴趣,可以尝试自行优化我们提供的线程池实现。我们给出的线程池实现简单完善且直观,用来学习再好不过。
502+
有些功能实现起来非常简单,而有些则需要更多的思考和设计。不过,这些功能超出了本次讲解的范围。如果有兴趣,可以尝试自行优化我们提供的线程池实现,添加更多的功能。我们给出的线程池实现简单完善且直观,用来学习再好不过。
503503

504504
## 总结
505505

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /