2012-07-25 2 views
9

왜 메모리에서 읽는 것이 스레드로부터 안전하지 않은지 궁금합니다. 지금까지 본 것 중에 특히 this 질문은 메모리에서 읽는 것이 스레드로부터 안전하지 않은 것으로 보입니다.읽기가 스레드로부터 안전하지 않은 이유는 무엇입니까?

저는 파이썬으로 잠시 동안 코딩을 해왔고 지금은 C++을 사용하고 있습니다. 파이썬에서의 읽기가 스레드로부터 안전하지 않다고 들었습니다.

내가 틀렸다면 제발 정정 해주세요. 그렇지 않다면 왜 메모리에서 읽는 것이 스레드로부터 안전하지 않은지 말해주십시오.

+1

: //en.wikipedia합니다.org/wiki/독자 - 작가 _ 문제 –

답변

15

읽기는 스레드로부터 안전하며 아무런 문제가 없습니다 ..... 읽고 쓰고있는 위치에 글을 쓸 때까지 ... 글쎄요, 데이터가 변경되기 전에 읽는 것이 좋을 것입니다. 데이터가 변경되었습니다 (이 경우 걱정하지 않아도 됨).하지만 가끔씩 정말로 원하지 않는 경우에는 글을 중간에 읽은 다음 가비지 데이터를 경쟁하게됩니다.

이 문제를 줄이려면 쓰기 전 또는 후에 읽기만 수행해야합니다. 쓰기가 수행되고 있는지 확인하고 일종의 동기화 잠금을 사용해야합니다. 이것은 당신이 분명히 자물쇠를 확인하고 읽는 대신에 읽는 것처럼 일을 더 느리게 만듭니다. 기본 데이터 유형 (예 : int)으로 작업하는 경우 CPU 동기화를 사용하여이를 극적으로 빠르게 할 수 있습니다.

fr 파이썬으로, 파이썬 데이터는 항상 언어 런타임에 의해 동기화됩니다. 그렇지 않으면 같은 스레드가 문제를 조만간 읽게됩니다. (빠른 구글은 예, Python will suffer the same problems는 당신이 조심하지 않는다는 것을 말합니다)

8

많은 스레드가 동일한 위치를 읽는 경우 아무도 스레드에 쓰기를 시도하지 않을 때 스레드로부터 안전합니다.

스레드 B가 스레드 B가 읽는 메모리에 쓰는 것과 동시에 뭔가를 읽는 경우를 고려하십시오. race condition을 생성합니다. 읽기 결과가 유효하지 않거나 시작과 실행이 다를 수 있습니다.

7

메모리에서 읽기는 스레드로부터 안전합니다. 메모리에서 읽기는 동시에 안전하지 않습니다.

많은 개체가 변경되지 않으므로 파이썬에서는 문제가되지 않으므로 메모리 자체가 아니라 참조 만 수정됩니다.

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_lenarr을 읽은 다음됩니다) arr[arr_len] 순차적으로 수행되는 것을 가정하자.

2 스레드가 인터리브 된 경우 어떻게됩니까? 세 가지의 하나가 발생할 수 있습니다

  • 문제 없습니다 - 당신이 운이 좋다 없습니다!
  • arr_lenarr보다 큰 - UB :(
  • arr은 무효화됩니다 (삭제) - UB :(내가 HTTP 읽는 것이 좋습니다
관련 문제