Skip to content

修复代码错误问题 #118

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Aug 28, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions book/en-us/07-thread.md
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,8 @@ struct A {
int y;
long long z;
};

int main() {
std::atomic<A> a;
std::cout << std::boolalpha << a.is_lock_free() << std::endl;
return 0;
Expand Down Expand Up @@ -427,7 +429,7 @@ In order to achieve the ultimate performance and achieve consistency of various
std::atomic<int> counter = {0};
std::vector<std::thread> vt;
for (int i = 0; i < 100; ++i) {
vt.emplace_back([](){
vt.emplace_back([&](){
counter.fetch_add(1, std::memory_order_relaxed);
});
}
Expand All @@ -442,7 +444,8 @@ In order to achieve the ultimate performance and achieve consistency of various
2. Release/consumption model: In this model, we begin to limit the order of operations between processes. If a thread needs to modify a value, but another thread will have a dependency on that operation of the value, that is, the latter depends. former. Specifically, thread A has completed three writes to `x`, and thread `B` relies only on the third `x` write operation, regardless of the first two write behaviors of `x`, then `A ` When active `x.release()` (ie using `std::memory_order_release`), the option `std::memory_order_consume` ensures that `B` observes `A` when calling `x.load()` Three writes to `x`. Let's look at an example:

```cpp
std::atomic<int*> ptr;
// initialize as nullptr to prevent consumer load a dangling pointer
std::atomic<int*> ptr(nullptr);
int v;
std::thread producer([&]() {
int* p = new int(42);
Expand Down Expand Up @@ -498,7 +501,7 @@ In order to achieve the ultimate performance and achieve consistency of various
std::atomic<int> counter = {0};
std::vector<std::thread> vt;
for (int i = 0; i < 100; ++i) {
vt.emplace_back([](){
vt.emplace_back([&](){
counter.fetch_add(1, std::memory_order_seq_cst);
});
}
Expand Down Expand Up @@ -546,4 +549,4 @@ They provide an critical foundation for standardized high performance computing

## Licenses

<a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/4.0/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-nd/4.0/88x31.png" /></a><br />This work was written by [Ou Changkun](https://changkun.de) and licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/4.0/">Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License</a>. The code of this repository is open sourced under the [MIT license](../../LICENSE).`
<a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/4.0/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-nd/4.0/88x31.png" /></a><br />This work was written by [Ou Changkun](https://changkun.de) and licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/4.0/">Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License</a>. The code of this repository is open sourced under the [MIT license](../../LICENSE).`
16 changes: 8 additions & 8 deletions book/zh-cn/04-containers.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,14 +186,14 @@ Key:[3] Value:[3]

auto get_student(int id)
{
// 返回类型被推断为 std::tuple<double, char, std::string>

if (id == 0)
return std::make_tuple(3.8, 'A', "张三");
if (id == 1)
return std::make_tuple(2.9, 'C', "李四");
if (id == 2)
return std::make_tuple(1.7, 'D', "王五");
// 返回类型被推断为 std::tuple<double, char, std::string>

if (id == 0)
return std::make_tuple(3.8, 'A', "张三");
if (id == 1)
return std::make_tuple(2.9, 'C', "李四");
if (id == 2)
return std::make_tuple(1.7, 'D', "王五");
return std::make_tuple(0.0, 'D', "null");
// 如果只写 0 会出现推断错误, 编译失败
}
Expand Down
9 changes: 6 additions & 3 deletions book/zh-cn/07-thread.md
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,8 @@ struct A {
int y;
long long z;
};

int main() {
std::atomic<A> a;
std::cout << std::boolalpha << a.is_lock_free() << std::endl;
return 0;
Expand Down Expand Up @@ -437,7 +439,7 @@ struct A {
std::atomic<int> counter = {0};
std::vector<std::thread> vt;
for (int i = 0; i < 100; ++i) {
vt.emplace_back([](){
vt.emplace_back([&](){
counter.fetch_add(1, std::memory_order_relaxed);
});
}
Expand All @@ -451,7 +453,8 @@ struct A {
2. 释放/消费模型:在此模型中,我们开始限制进程间的操作顺序,如果某个线程需要修改某个值,但另一个线程会对该值的某次操作产生依赖,即后者依赖前者。具体而言,线程 A 完成了三次对 `x` 的写操作,线程 `B` 仅依赖其中第三次 `x` 的写操作,与 `x` 的前两次写行为无关,则当 `A` 主动 `x.release()` 时候(即使用 `std::memory_order_release`),选项 `std::memory_order_consume` 能够确保 `B` 在调用 `x.load()` 时候观察到 `A` 中第三次对 `x` 的写操作。我们来看一个例子:

```cpp
std::atomic<int*> ptr;
// 初始化为 nullptr 防止 consumer 线程从野指针进行读取
std::atomic<int*> ptr(nullptr);
int v;
std::thread producer([&]() {
int* p = new int(42);
Expand Down Expand Up @@ -507,7 +510,7 @@ struct A {
std::atomic<int> counter = {0};
std::vector<std::thread> vt;
for (int i = 0; i < 100; ++i) {
vt.emplace_back([](){
vt.emplace_back([&](){
counter.fetch_add(1, std::memory_order_seq_cst);
});
}
Expand Down
7 changes: 4 additions & 3 deletions code/7/7.8.memory.order.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@
using namespace std;
using namespace std::chrono;

atomic<int> counter = {0};
const int N = 10000;

void relaxed_order() {
cout << "relaxed_order: " << endl;

atomic<int> counter = {0};
vector<thread> vt;
for (int i = 0; i < N; ++i) {
vt.emplace_back([](){
vt.emplace_back([&](){
counter.fetch_add(1, memory_order_relaxed);
});
}
Expand Down Expand Up @@ -86,9 +86,10 @@ void release_acquire_order() {
void sequential_consistent_order() {
cout << "sequential_consistent_order: " << endl;

atomic<int> counter = {0};
vector<thread> vt;
for (int i = 0; i < N; ++i) {
vt.emplace_back([](){
vt.emplace_back([&](){
counter.fetch_add(1, memory_order_seq_cst);
});
}
Expand Down