2011-05-11 3 views
1

나는 C++에서 리눅스 다중 스레드 응용 프로그램을 가지고 있습니다. class App 제공 변수 Status에서이 응용 프로그램에서 :pthreads 응용 프로그램에서 할당

class App { 
... 
typedef enum { asStop=0, asStart, asRestart, asWork, asClose } TAppStatus; 
TAppStatus Status; 
... 
} 

모든 스레드가 종종 GetStatus() 함수를 호출하여 Status을 확인하고 있습니다. 응용 프로그램의

inline TAppStatus App::GetStatus(){ return Status }; 

다른 기능 SetStatus() 함수를 호출하여 Status 변수에 다른 값을 지정할 수 있으며, 뮤텍스를 사용하지 마십시오.

void App::SetStatus(TAppStatus aStatus){ Status=aStatus }; 

편집 : 모든 스레드 switch 연산자 Status를 사용

switch (App::GetStatus()){ case asStop: ... case asStart: ... }; 
  1. 이 경우 할당, 원자 조작인가?
  2. 올바른 코드입니까?

감사합니다.

+0

저는 열거 형이 스레드 세이프 (threadesafe)한지 의심 스럽습니다 ... 할당이 원자 적 연산이라는 것을 의심합니다. –

답변

3

C99 또는 C++ 03에서 동기화 된 변수를 구현할 수있는 이식성있는 방법이 없으며 pthread 라이브러리는이 중 하나를 제공하지 않습니다. 할 수 있습니다 :

  • 를 사용하여 C++ 0X <atomic> 헤더 (또는 C1x <stdatomic.h>). Gcc는 버전 4.4 이후로 -std=c++0x 또는 -std=gnu++0x 옵션이 주어진 경우 C++ 용으로이를 지원합니다.
  • 리눅스 전용 <linux/atomic.h>을 사용하십시오 (이것은 커널에서 사용되는 구현이지만 사용자 영역에서도 사용할 수 있어야합니다).
  • GCC 관련 __sync_* builtin functions을 사용하십시오.
  • glib과 같은 원자 적 조작을 제공하는 다른 라이브러리를 사용하십시오.
  • 잠금 장치를 사용하십시오.하지만 잠금 장치는 빠른 작동 자체보다 느립니다.

참고 : Martinho가 지적했듯이 스토어 및로드의 경우 원자 속성 (atomic 속성)이 아닙니다 (작업을 중단 할 수 없으며 항상로드가 표시되거나 전체 스토어가 표시되지 않습니다. 32 비트 저장소 및로드의 경우)하지만 순서 특성 (a 및 b를 저장하면 아무도 b의 새로운 값을 얻을 수 있고 이전 값인 a보다 작음)은 얻을 수 없지만이 경우 필요합니다.

+0

죄송합니다. "Linux 관련"은 무엇입니까? 거기에 한 마디도 잊지 않았 니? –

+0

@Martinho : 죄송합니다, 죄송합니다. 따옴표를 잊어 버리므로'<>'의 헤더 이름이 삭제되었습니다. –

0

이것은 전적으로 선택한 enum 표현에 따라 결정됩니다. x86의 경우, 운영 체제의 워드 크기 (x86의 경우 32 비트, x64의 경우 64 비트)와 그 크기의 정렬 작업도 모두 원자 적이므로 읽기 및 쓰기가 단순합니다.

심지어이 이 기능은 스레드 안전하다는 것을 의미하지는 않는, 올바른 크기 정렬라고 가정하면, 상태가 사용되는지에 따라 달라집니다.

편집 : 또한 원자 적 연산이나 다른 일시적인 액세스가 사용되지 않으면 컴파일러의 최적화 프로그램으로 인해 큰 혼란이 발생할 수 있습니다.

수정 사항 편집 : 아니요, 스레드로부터 안전하지 않습니다. 수동으로 점프 테이블로 변환하면 스레드로부터 안전 할 수 있습니다. 잠시 생각해 봐야합니다.

+0

'휘발성'키워드가 없으면 절대 아예 없습니다. –

+2

"휘발성 변수에 대한 연산은 원 자성이 아니며 스레딩에 대해 적절한 발생 - 관계를 확립하지도 않습니다." 휘발성이란 "어이, 거기 컴파일러가이 일에 대한 액세스를 최적화하지 않습니까?"라는 의미입니다. –

+0

@Martinho : 물건을 휘발성으로 선언하는 일부 플랫폼에서는 저장소를 저장하고 원자를로드하기에 충분하며 "액세스 최적화 안 함"은 "일부 시퀀싱 지점에서 순서를 바꾸지 마십시오"는 의미로 일부 플랫폼에서는 순서를 정의하기에 충분합니다 (명령어는 올바르게 정렬되었지만 캐시는이를 깨뜨릴 수 있습니다). –

0

특정 아키텍처에서이 할당은 원 자상 (우연히) 일 수 있습니다. 그러나 실제로이 코드는 잘못되었습니다. 컴파일러와 하드웨어는이 "원 자성"을 깨뜨릴 수 있으므로 다양한 최적화를 수행 할 수 있습니다. 살펴보기 : http://video.google.com/videoplay?docid=-4714369049736584770#

수정하려면 잠금 또는 원자 http://www.stdthread.co.uk/doc/headers/atomic/atomic.html 변수를 사용하십시오.

+0

'std :: atomic'은 C++ 0x 만 사용합니다. –