文章目录
对象、内存位置和并发
一个对象无论是基础类型还是自定义类型,这个对象都会存储在一个或多个内存位置上。
在多线程程序中,如果两个线程访问不同的内存位置,往往不会有什么问题。但当它们访问同一个内存位置时,如果该位置上的数据被更新了,那么就会产生条件竞争,这是多线程程序常见的问题。
解决的方式就像之前所说的,使用互斥量来保护共享数据,同一时间只能有一个线程能够访问,另一个线程必须要在前一个线程访问结束释放锁以后才能够访问。
而另外一种方式,是使用原子操作来决定两个线程的访问顺序。由于它不用加锁解锁,所以效率上会比使用互斥量高一些,但原子操作的保护对象通常是一个对象而不是一个代码段。
原子操作
原子操作是不可分的操作,要么做了,要么没做。
标准原子类型定义在头文件 <atomic>
中,这些类型的所有操作都是原子的,通常用在并发程序中对变量或对象的原子操作,这样的原子操作一般都比较简单,比如计数等等。
例如,我们使用原子操作来代替互斥量保护我们的 T 类型的对象
在上面的例子中,对自增操作++,以及 += 等复合操作,都是线程安全的。但如果我们改成:
t.m_i = t.m_i