@@ -162,17 +162,17 @@ struct trivial_type {
162162};
163163```
164164
165- 验证自己的类型是否满足 ` std::atomic ` 要求,我们可以这样做 :
165+ 验证自己的类型是否满足 ` std::atomic ` 要求,我们可以使用 [ 静态断言 ] ( https://zh.cppreference.com/w/cpp/language/static_assert ) :
166166
167167``` cpp
168- std::cout << std::boolalpha << std:: is_trivially_copyable<trivial_type>::value << ' \n ' ;
169- std::cout << std::boolalpha << std:: is_copy_constructible<trivial_type>::value << ' \n ' ;
170- std::cout << std::boolalpha << std:: is_move_constructible<trivial_type>::value << ' \n ' ;
171- std::cout << std::boolalpha << std:: is_copy_assignable<trivial_type>::value << ' \n ' ;
172- std::cout << std::boolalpha << std:: is_move_assignable<trivial_type>::value << ' \n ' ;
168+ static_assert ( std::is_trivially_copyable<trivial_type>::value, " " ) ;
169+ static_assert ( std::is_copy_constructible<trivial_type>::value, " " ) ;
170+ static_assert ( std::is_move_constructible<trivial_type>::value, " " ) ;
171+ static_assert ( std::is_copy_assignable<trivial_type>::value, " " ) ;
172+ static_assert ( std::is_move_assignable<trivial_type>::value, " " ) ;
173173```
174174
175- 只要全部为 ` true ` 即可 。显然我们的类型满足要求,我们可以尝试使用一下它:
175+ 程序能通过编译即代表满足要求。如果不满足要求,静态断言求值中第一个表达式求值为 false,则编译错误 。显然我们的类型满足要求,我们可以尝试使用一下它:
176176
177177``` cpp
178178// 创建一个 std::atomic<trivial_type> 对象
@@ -191,7 +191,7 @@ std::cout << "交换前的 x: " << exchanged_value.x << ", 交换前的 y: " <<
191191std::cout << "交换后的 x: " << atomic_my_type.load().x << ", 交换后的 y: " << atomic_my_type.load().y << std::endl;
192192```
193193
194- > [运行](https://godbolt.org/z/eTW64nGMz )测试。
194+ > [运行](https://godbolt.org/z/jG59c3b9M )测试。
195195
196196没有问题,不过其实我们的 `trivial_type` 直接改成:
197197
@@ -202,7 +202,7 @@ struct trivial_type {
202202};
203203```
204204
205- > [ 运行] ( https://godbolt.org/z/4oTf996xK ) 测试。
205+ > [ 运行] ( https://godbolt.org/z/ozPK1qefx ) 测试。
206206
207207也是完全可以的,满足要求。先前只是为了展示一下显式写明的情况。
208208
@@ -295,6 +295,14 @@ void f(){
295295
296296当 ` flag ` 对象的状态为设置 (` true ` ) 时,其线程调用 ` test_and_set ` 函数会返回 ` true ` ,导致它们继续在循环中自旋,无法退出。直到先前持有锁的线程调用 ` unlock() ` 函数,将 ` flag ` 对象的状态原子地更改为清除 (` false ` ) 状态。此时,等待的线程中会有一个线程成功调用 ` test_and_set ` 返回 ` false ` ,然后退出循环,成功获取锁。
297297
298+ > 值得注意的是,我们只是稍微的讲一下使用 ` std::atomic_flag ` 实现自旋锁。不过可没推荐各位在实践中使用它,具体可参见 ** Linus Torvalds** 的[ 文章] ( https://www.realworldtech.com/forum/?threadid=189711&curpostid=189723 ) 。其中有一段话说的很直接:
299+ >
300+ > - I repeat: ** do not use spinlocks in user space, unless you actually know what you're doing** . And be aware that the likelihood that you know what you are doing is basically nil.
301+ >
302+ > > 我再说一遍:不要在用户空间中使用自旋锁,除非你真的知道自己在做什么。请注意,你知道自己在做什么的可能性基本上为零。
303+ >
304+ > 然后就是推荐 ` std::mutex ` 、` pthread_mutex ` ,比自旋好的多。
305+
298306` std::atomic_flag ` 的局限性太强,甚至不能当普通的 bool 标志那样使用。一般最好使用 ` std::atomic<bool> ` ,下节,我们来使用它。
299307
300308## 内存次序
0 commit comments