2012-07-25 32 views
9

我想知道为什么从内存中读取不是线程安全的。在我迄今为止所看到的,尤其是this的问题中,从内存中读取看起来不是线程安全的。为什么阅读不是线程安全的?

我一直在Python中编写一段时间,现在进入C++。我从来没有听说过Python中的读取不是线程安全的。

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

+1

我会推荐阅读HTTP://en.wikipedia。组织/维基/读者,writers_problem – 2012-07-25 10:37:48

回答

15

阅读是线程安全的,没有问题.....直到有东西写到您正在阅读的位置,然后......好吧,希望您在数据更改之前阅读,或阅读数据发生了变化(在这些情况下,不用担心),但有时候,只是当你真的不需要它时,你会在写入过程中读取一半,然后你会得到竞争的垃圾数据。

缓解这种情况的方法是确保您只在任何写入之前或之后读取,这需要您检查写入是否正在发生,从而使用某种类型的同步锁定。尽管如此,这会让事情变得更慢,因为你显然正在检查锁,然后阅读而不是阅读。如果您使用的是原始数据类型(例如int),那么您可以使用CPU同步来显着提高速度。

作为Python的Python,很有可能Python语言的数据总是通过语言运行时为您同步,如果不是,那么您迟早会得到相同的线程读取问题。 (快速谷歌说是,Python will suffer the same problems是你不小心)

8

如果许多线程正在读取相同的位置,直到没有人试图在那里写入,则它是线程安全的。

考虑线程A是否在线程B正在读取的内存中写入数据的同时读取某些内容。它会生成一个race condition。读取结果可能会变得无效或从启动到启动

7

从内存中读取是线程安全的,从可以同时写入的内存中读取并不安全。

在Python中,由于许多对象是不可变的,所以只有引用在这些情况下被修改,而不是内存本身。

0

同时读同一件事 - 是安全的。 问题是当某些东西在同一时间写入它时。

考虑下面的代码:

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_lenarr大 - UB :(
  • arr无效(已删除) - UB :(
相关问题