2016-08-20 3 views
2

A, B, C 세 개의 스레드가있는 프로그램을 생각해 보겠습니다.스레드 내에서 원자 변수 사용

그들은 공유 전역 객체 G.

나는 A.에 의해 스레드 B에 의해 작성 및 읽기되고 G 내부 원자 변수 (i)를 사용하려면이

내 방식이었다

G에

선언 난 같이

:

std::atomic<int> i; 

기록 스레드 B로부터는 G로의 포인터를 사용하여

G* pG; //this is available inside A and B 

pG->i = 23; 

그리고 같은 방법으로 스레드 A에서 읽습니다.

int k = pG->i; 

이 스레드가이 변수에 동시에 액세스하려고하면 올바른 방법이 있습니까?

+1

B가 쓰기 전에 스레드 A가 값을 읽는다면 프로그램이 얼마나 정확합니까? – JVApen

+0

@JVApen 스레드 A는 사용할 수있는 (초기화 된) 값을 취합니다. –

+1

이 경우 2 개의 스레드에서 i에 액세스하는 것이 정확합니다. 액세스 할 때 스레드 중 하나가 먼저 나타나고 다른 스레드는 변경 사항을 보게됩니다. – JVApen

답변

2

JV가 말했듯이 "올바른"정의가 무엇인지에 달려 있습니다. http://preshing.com/20120612/an-introduction-to-lock-free-programming/을 참조하십시오. 다른 것과 동기화 할 필요가없는 경우 기본 순차 일관성 저장소 대신 std::memory_order_relaxed 저장소를 사용해야하므로보다 효율적인 asm (메모리 장벽 지침 없음)으로 컴파일됩니다.

하지만 포인터를 통해 원자 구조체 멤버에 액세스하는 것은 포인터 자체가 스레드가 시작되기 전에 초기화되는 한 잘 수행됩니다.

구조체가 전역이면 포인터를 사용하지 말고 전역 변수에 직접 액세스하십시오. 항상 동일한 글로벌을 가리키는 별도의 변수를 갖는 것은 이점을 얻지 못하는 간접적 인 수준입니다.

포인터를 변경하려면 포인터를 변경하려면 std::atomic<struct foo *> pG이어야하며 이전 데이터를 변경 한 후에도 안전하게 해제 할 수 있는지 결정하는 것은 복잡합니다.

관련 문제