Logo
Section 1 / 16

共享数据简介

本课程介绍了在 C++ 中如何在线程之间共享数据。

导入

共享数据简介

本课程介绍了在 C++ 中如何在线程之间共享数据。

我们只需要在存在共享可变数据时才考虑同步问题,因为这类数据容易引发【数据竞争】(data races)。如果对数据进行并发的非同步读写访问,程序将产生未定义行为。可视化并发且未同步的读写操作最简单的方式,就是向 std::cout 输出内容。让我们来看一个例子:

1// coutUnsynchronised.cpp 2 3#include <chrono> 4#include <iostream> 5#include <thread> 6 7class Worker { 8public: 9 Worker(std::string n) : name(n) {} 10 void operator()() { 11 for (int i = 1; i <= 3; ++i) { 12 // 开始工作 13 std::this_thread::sleep_for(std::chrono::milliseconds(200)); 14 // 结束工作 15 std::cout << name << ": " << "Work " << i << " done !!!" << std::endl; 16 } 17 } 18private: 19 std::string name; 20}; 21 22int main() { 23 std::cout << std::endl; 24 25 std::cout << "Boss: Let's start working.\n\n"; 26 27 std::thread herb = std::thread(Worker("Herb")); 28 std::thread andrei = std::thread(Worker(" Andrei")); 29 std::thread scott = std::thread(Worker(" Scott")); 30 std::thread bjarne = std::thread(Worker(" Bjarne")); 31 std::thread bart = std::thread(Worker(" Bart")); 32 std::thread jenne = std::thread(Worker(" Jenne")); 33 34 herb.join(); 35 andrei.join(); 36 scott.join(); 37 bjarne.join(); 38 bart.join(); 39 jenne.join(); 40 41 std::cout << "\n" << "Boss: Let's go home." << std::endl; 42 43 std::cout << std::endl; 44}

经理-工人模型

在经理-工人模型中,一个线程(经理)负责接收整个程序的输入。根据输入内容,经理将具体任务分配给一个或多个工人线程。在上面的代码中,经理有六个工人(第29至34行),每个工人需要完成3个任务包。每个任务包耗时1/5秒(第13行)。当工人完成任务包后,会大声向经理报告(第15行)。一旦经理收到所有工人的通知,就让他们回家(第44行)。


这看起来真是乱成一团,仅仅是一个简单的流程而已!最直接的解决方案是使用互斥锁(mutex),我们将在下一课中学习。

线程

互斥锁简介