我想知道为什么从内存中读取不是线程安全的。在我迄今为止看到的内容中,特别是this问题,从内存中读取似乎不是线程安全的。
我已经在Python编写了一段时间,现在进入C ++。我从来没有听说过用Python阅读不是线程安全的。
如果我错了,请纠正我,但如果没有,请告诉我为什么从内存中读取不是线程安全的。
答案 0 :(得分:18)
读取是线程安全的,没有问题.....直到某些内容写入您正在读取的位置,然后......好吧,希望您在数据更改之前阅读,或者在数据之后读取改变了(在这些情况下,没有后顾之忧),但有时候,当你真的不想要它时,你会在写入中途阅读,然后你将获得竞争垃圾数据。
缓解此问题的方法是确保您只在读取之前或之后读取,这要求您检查是否正在进行写入,从而使用某种类型的同步锁定。这会使事情变慢,因为你显然是在检查锁定然后阅读而不是阅读。如果您正在使用原始数据类型(例如int),那么您可以使用CPU同步来显着提高速度。
作为fr Python,语言运行时总是可以为你同步python数据,如果不是,那么你迟早会得到相同的线程读取问题。 (快速谷歌说是的,Python will suffer the same problems你不小心)
答案 1 :(得分:9)
如果许多线程正在读取相同的位置,那么它是线程安全的,直到没有人尝试在那里写入。
考虑线程A是否正在读取某些内容,因为线程B正在读取正在读取的内存。它将生成race condition
。阅读结果可能无效或与启动到启动不同
答案 2 :(得分:8)
从内存中读取是线程安全的,但是从可以同时写入的内存中读取是不安全的。
在Python中,这不是一个问题,因为很多对象是不可变的,因此在这些情况下只修改引用,而不是内存本身。
答案 3 :(得分:1)
同时阅读同一件事 - 是安全的。 问题是当某些东西同时写入它时。
请考虑以下代码:
int arr_len = 3;
int* arr = new int[arr_len];
void thread_1()
{
std::cout << arr[arr_len-1];
}
void thread_2(int new_len)
{
int* temp = new int[new_len];
for(int i = 0; i < arr_len && i < new_len; ++i)
temp[i] = arr[i];
arr_len = new_len;
delete arr;
arr = temp;
}
我们假设arr[arr_len]
按顺序完成(首先读取arr_len
,然后arr
)。
当2个线程交错运行时会发生什么? 可能发生以下三种情况之一:
arr_len
大于arr
- UB :( arr
无效(已删除) - UB:(