为什么阅读不是线程安全的?

时间:2012-07-25 10:33:07

标签: c++ thread-safety

我想知道为什么从内存中读取不是线程安全的。在我迄今为止看到的内容中,特别是this问题,从内存中读取似乎不是线程安全的。

我已经在Python编写了一段时间,现在进入C ++。我从来没有听说过用Python阅读不是线程安全的。

如果我错了,请纠正我,但如果没有,请告诉我为什么从内存中读取不是线程安全的。

4 个答案:

答案 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:(