std::get<C++11多线程库~线程间共享数据>(09):共享数据带来的问题(1)

 1 #include <QCoreApplication>
 2 
 3 /*
 4  * 话题1:线程间共享数据
 5  *      a. 共享数据带来的问题
 6  *      b. 使用互斥量保护数据
 7  *      c. 数据保护的替代方案
 8  *
 9  *      多个线程只读的访问某一个相同的数据,不会出现问题;
10  *      多个线程有读有些的访问某一个相同的数据,可能会出现问题;
11  *      因此,当线程访问共享数据的时候,必须添加一些措施来约束对共享数据的访问。另外,某个线程修改了共享数据,还需要通知其他线程数据发生了变化。
12  *
13  * 1.1 共享数据带来的问题
14  *      a. 条件竞争
15  *      b. 避免恶性条件竞争
16  *
17  *      条件竞争(race condition):多个线程争夺同一资源。对共享资源的修改是否具备“原子性”非常关键,如果具备,则不会出问题,否则就是梦魇的开始。
18  *      数据竞争:C++标准中定义了一种特殊的条件竞争:并发的去修改一个独立对象,数据竞争是(可怕的)未定义行为的起因。
19  *      原子性:一个操作在CPU上一次能执行完毕,则称之为原子性操作,原子性操作是安全的。而非原子性操作,常常会因为“操作系统时间切片”的缘故,操作被切断,资源被另一线程
20  * 抢夺,非原子性操作是不安全的。
21  *      条件竞争通常是时间敏感的,所以程序以调试模式运行时,它们常会完全消失,因为调试模式会影响程序的执行时间(即使影响不多)。
22  *
23  *      解决恶性条件竞争,最简单的办法就是对数据结构采用某种保护机制,确保当存在写数据的线程,只有当前修改共享数据的线程能处理数据的中间状态,
24  * 而其他线程只能等待,对其他线程而言,能够访问的共享数据状态,要么被修改还未开始,要么被修改已经结束。
25  *      C++标准库提供很多类似的机制,下面会逐一介绍:
26  *      第一种:对数据结构的设计进行修改,每个操作必须能完成一系列不可分割的变化,,这就是所谓的无锁编程。
27  *      第二种:使用事务的方式去处理数据结构的更新。类似于数据库事务的概念。  有一个相关的概念:“软件事务内存”(software transactional memory (STM))。
28  *
29  *      保护共享数据结构的最基本的方式,是使用C++标准库提供的互斥量。
30  *
31  *
32 */
33 int main(int argc, char *argv[])
34 {
35     QCoreApplication a(argc, argv);
36 
37     return a.exec();
38 }
原文地址:https://www.cnblogs.com/azbane/p/15383014.html