mirror of
https://github.com/changkun/modern-cpp-tutorial.git
synced 2025-12-16 12:17:08 +03:00
book: revise usage of "mutex" and "instantiation" (#292)
This commit is contained in:
@@ -31,7 +31,7 @@ int main() {
|
||||
We have already learned the basics of concurrency technology in the operating system, or the database, and `mutex` is one of the cores.
|
||||
C++11 introduces a class related to `mutex`, with all related functions in the `<mutex>` header file.
|
||||
|
||||
`std::mutex` is the most basic `mutex` class in C++11, and you can create a mutex by instantiating `std::mutex`.
|
||||
`std::mutex` is the most basic mutex class in C++11, and a mutex can be created by constructing a `std::mutex` object.
|
||||
It can be locked by its member function `lock()`, and `unlock()` can be unlocked.
|
||||
But in the process of actually writing the code, it is best not to directly call the member function,
|
||||
Because calling member functions, you need to call `unlock()` at the exit of each critical section, and of course, exceptions.
|
||||
@@ -160,7 +160,7 @@ After encapsulating the target to be called, you can use `get_future()` to get a
|
||||
The condition variable `std::condition_variable` was born to solve the deadlock and was introduced when the mutex operation was not enough.
|
||||
For example, a thread may need to wait for a condition to be true to continue execution.
|
||||
A dead wait loop can cause all other threads to fail to enter the critical section so that when the condition is true, a deadlock occurs.
|
||||
Therefore, the `condition_variable` instance is created primarily to wake up the waiting thread and avoid deadlocks.
|
||||
Therefore, the `condition_variable` object is created primarily to wake up the waiting thread and avoid deadlocks.
|
||||
`notify_one()` of `std::condition_variable` is used to wake up a thread;
|
||||
`notify_all()` is to notify all threads. Below is an example of a producer and consumer model:
|
||||
|
||||
@@ -276,8 +276,8 @@ This is a very strong set of synchronization conditions, in other words when it
|
||||
This seems too harsh for a variable that requires only atomic operations (no intermediate state).
|
||||
|
||||
The research on synchronization conditions has a very long history, and we will not go into details here. Readers should understand that under the modern CPU architecture, atomic operations at the CPU instruction level are provided.
|
||||
Therefore, in the C++11 multi-threaded shared variable reading and writing, the introduction of the `std::atomic` template, so that we instantiate an atomic type, will be an
|
||||
Atomic type read and write operations are minimized from a set of instructions to a single CPU instruction. E.g:
|
||||
Therefore, the `std::atomic` template is introduced in C++11 for the topic of multi-threaded shared variable reading and writing, which enables us to instantiate atomic types,
|
||||
and minimize an atomic read or write operation from a set of instructions to a single CPU instruction. E.g:
|
||||
|
||||
```cpp
|
||||
std::atomic<int> counter;
|
||||
|
||||
@@ -31,7 +31,7 @@ int main() {
|
||||
我们在操作系统、亦或是数据库的相关知识中已经了解过了有关并发技术的基本知识,`mutex` 就是其中的核心之一。
|
||||
C++11 引入了 `mutex` 相关的类,其所有相关的函数都放在 `<mutex>` 头文件中。
|
||||
|
||||
`std::mutex` 是 C++11 中最基本的 `mutex` 类,通过实例化 `std::mutex` 可以创建互斥量,
|
||||
`std::mutex` 是 C++11 中最基本的互斥量类,可以通过构造 `std::mutex` 对象创建互斥量,
|
||||
而通过其成员函数 `lock()` 可以进行上锁,`unlock()` 可以进行解锁。
|
||||
但是在实际编写代码的过程中,最好不去直接调用成员函数,
|
||||
因为调用成员函数就需要在每个临界区的出口处调用 `unlock()`,当然,还包括异常。
|
||||
@@ -163,7 +163,7 @@ int main() {
|
||||
条件变量 `std::condition_variable` 是为了解决死锁而生,当互斥操作不够用而引入的。
|
||||
比如,线程可能需要等待某个条件为真才能继续执行,
|
||||
而一个忙等待循环中可能会导致所有其他线程都无法进入临界区使得条件为真时,就会发生死锁。
|
||||
所以,`condition_variable` 实例被创建出现主要就是用于唤醒等待线程从而避免死锁。
|
||||
所以,`condition_variable` 对象被创建出现主要就是用于唤醒等待线程从而避免死锁。
|
||||
`std::condition_variable`的 `notify_one()` 用于唤醒一个线程;
|
||||
`notify_all()` 则是通知所有线程。下面是一个生产者和消费者模型的例子:
|
||||
|
||||
@@ -283,8 +283,7 @@ int main() {
|
||||
这对于一个仅需原子级操作(没有中间态)的变量,似乎太苛刻了。
|
||||
|
||||
关于同步条件的研究有着非常久远的历史,我们在这里不进行赘述。读者应该明白,现代 CPU 体系结构提供了 CPU 指令级的原子操作,
|
||||
因此在 C++11 中多线程下共享变量的读写这一问题上,还引入了 `std::atomic` 模板,使得我们实例化一个原子类型,将一个
|
||||
原子类型读写操作从一组指令,最小化到单个 CPU 指令。例如:
|
||||
因此在多线程下共享变量的读写这一问题上, C++11 中还引入了 `std::atomic` 模板,使得我们能实例化原子类型,并将一个原子写操作从一组指令,最小化到单个 CPU 指令。例如:
|
||||
|
||||
```cpp
|
||||
std::atomic<int> counter;
|
||||
|
||||
Reference in New Issue
Block a user