File tree 1 file changed +17
-2
lines changed
1 file changed +17
-2
lines changed Original file line number Diff line number Diff line change @@ -125,10 +125,25 @@ while (!pred())
125
125
wait(lock);
126
126
```
127
127
128
- 这可以避免“[ 虚假唤醒(spurious wakeup)] ( https://en.wikipedia.org/wiki/Spurious_wakeup ) ”。
128
+ 第二个版本只是对第一个版本的 ** 包装 ** ,等待并判断谓词,会调用第一个版本的重载。 这可以避免“[ 虚假唤醒(spurious wakeup)] ( https://en.wikipedia.org/wiki/Spurious_wakeup ) ”。
129
129
130
130
> 条件变量虚假唤醒是指在使用条件变量进行线程同步时,有时候线程可能会在没有收到通知的情况下被唤醒。问题取决于程序和系统的具体实现。解决方法很简单,在循环中等待并判断条件可一并解决。使用 C++ 标准库则没有这个烦恼了。
131
131
132
+ 我们也可以简单看一下 MSVC STL 的[ 源码实现] ( https://github.com/microsoft/STL/blob/22a8826/stl/inc/mutex#L555-L565 ) :
133
+
134
+ ``` cpp
135
+ void wait (unique_lock<mutex >& _ Lck) noexcept {
136
+ _ Cnd_wait(_ Mycnd(), _ Lck.mutex()->_ Mymtx());
137
+ }
138
+
139
+ template <class _Predicate >
140
+ void wait(unique_lock<mutex >& _ Lck, _ Predicate _ Pred) {
141
+ while (!_ Pred()) {
142
+ wait(_ Lck);
143
+ }
144
+ }
145
+ ```
146
+
132
147
## 线程安全的队列
133
148
134
149
在本节中,我们介绍了一个更为复杂的示例,以巩固我们对条件变量的学习。为了实现一个线程安全的队列,我们需要考虑以下两个关键点:
@@ -1328,7 +1343,7 @@ int main() {
1328
1343
1329
1344
### ` std::latch `
1330
1345
1331
- “闩”,这个字其实个人觉得是不常见,“ ** 门闩** ” 是指门背后用来关门的棍子。好了好了,不用在意, 在 C++ 中就是先前说的: * 单次使用的线程屏障* 。
1346
+ “* 闩 * ” ,中文语境一般说“ * 门闩* ” 是指门背后用来关门的棍子。不过不用在意, 在 C++ 中的意思就是先前说的: *** 单次使用的线程屏障** * 。
1332
1347
1333
1348
` latch ` 类维护着一个 [ ` std::ptrdiff_t ` ] ( https://zh.cppreference.com/w/cpp/types/ptrdiff_t ) 类型的计数[ ^ 6 ] ,且只能** 减少** 计数,** 无法增加计数** 。在创建对象的时候初始化计数器的值。线程可以阻塞,直到 latch 对象的计数减少到零。由于无法增加计数,这使得 ` latch ` 成为一种** 单次使用的屏障** 。
1334
1349
You can’t perform that action at this time.
0 commit comments