Microsoft MVP성태의 닷넷 이야기
volatile 키워드 관련 질문입니다. [링크 복사], [링크+제목 복사]
조회: 10675
글쓴 사람
이성환 (vactorman at naver.com)
홈페이지
첨부 파일

스레드 사용 중에 volatile 키워드가 어떻게 동작하는 지 알아보려고 몇 가지 예제를 만들었습니다.

첨부한 예제 중에 다른 예제들은 예상한대로 동작을 하고 있는데요.

ValueUpdateTest 예제에서 이해할 수 없는 결과가 나와서 질문드립니다.

첨부한 내용을 보시면 바로 아시겠지만

Release로 빌드된 예제를 Ctrl + F5나 실행 파일로 실행해보면

메인 메서드 내부에

p._seed = 0;

이 코드가 동작하지 않는 것처럼 보입니다.

몇 번을 돌려봐도 마찬가지이고

Sleep을 짧게 줘서 t1의 동작이 실행 중인 상황에서는

p._seed 에 다른 값을 할당해도 들어가지 않네요.

그런데 이상한 건 CMD 창을 껐다 다시 켰을 때 최초 실행에서는 정상적으로

p._seed = 0 이 값이 할당 되는 것으로 표시됩니다. 그래서 JITter의 영향을 의심했는데

그 이후에는 매우 간헐적으로 p._seed = 0 이 할당되는 것으로 확인되어서

JITter 의 영향이라고 확신할 수가 없네요.
(JITter 문제라 해도 정확히 뭐가 문제인지는 모르겠습니다.)

대다수의 경우에는 t1의 for 루프 내부의 연산된 값이 표시되는 것으로 보입니다.

IL을 확인해봐도 분명히 p._seed에 0을 할당하는 구문이 생성되어 있는데요.

혹시나 해서 디버그 빌드 후 BP를 걸어서 확인해봤는데

디버그에서도 p._seed = 0; 할당문 직후에 값을 확인해 보면

0이 들어가지 않은 것으로 표시됩니다. (for 루프의 연산 중인 값이 표시됩니다)


점점 머릿속이 복잡해지는데요.

다른 예제에서 스레드가 Program 인스턴스의 필드를 사용하는 경우

참조로 전달된 인스턴스가 값복사 한 것처럼 동작하는 것은 또 어떻게 이해해야하는지


ValueUpdateTest 예제에서 스레드 별 메모리 영역이 동기화 되지 않는 다고 하더라도

메인 스레드가 직접 할당하는 값이 무시되는 것처럼 보이는게 이해가 잘 안 됩니다.


스레드 동작 방식과 스레드에 전달한 파라미터의 관계 자체가 다시 이해가 안 되기 시작합니다.


이쯤되면 스레드 사용하기가 점점 무서워지는데요.

volatile 키워드 없이 동기화를 하는 것이 정상 동작하는 지도 의심이 됩니다.


테스트 환경은 Win7 64bit i7 920에 6G 메모리 입니다.


도움 부탁 드립니다.










[최초 등록일: ]
[최종 수정일: 4/12/2013]


비밀번호

댓글 작성자
 



2013-04-15 01시10분
엄밀히 이건 volatile 의 문제는 아니고 동기화의 문제입니다. PrintType1 스레드에서 p._seed ++ 는 3가지 동작으로 이뤄집니다.

1. p._seed 의 값을 읽고,
2. p._seed 의 값을 증가하고,
3. p._seed 의 값을 쓴다.

따라서, Main 을 실행하는 스레드에서 값을 대입하는 p._seed = 0 가 제대로 동작하려면 반드시 3번 단계를 지나 1번 단계를 실행하기 전에 처리되어야 합니다. 이 현상은 매우 확률적으로 나타날 수 있기 때문에 '간헐적으로 할당'되는 것처럼 보이는 것이 맞습니다. 이를 확인하기 위해 해당 예제를 약간 변경해 다음의 경로에 올려두었으니 다운로드 받아서 실행해 보세요.

modified_VolatileTest
; https://skydrive.live.com/redir?resid=961704F5F30E2977!475

확률적이므로 경우에 따라서 한참 걸릴 수도 있지만, 결국에 한번은 0으로 초기화하는 코드가 동작하는 것을 확인할 수 있습니다.

만약, 원래 의도했던 데로 정확하게 실행하도록 프로그램을 바꾸고 싶다면 다음과 같이 코드를 수정해 주면 됩니다.

p._seed = 0; ==> Interlocked.Exchange(ref p._seed, 0);

p._seed ++; ==> Interlocked.Increment(ref p._seed);
정성태
2013-04-16 12시14분
[이성환] 답변 감사드립니다.

이 예제를 만들어 테스트 한 이유는 volatile의 설명 중에

"항상 최신값을 유지할 수 있다"는 표현 때문이었습니다.

제가 이 표현을 곡해했다고 봐야할 듯 하네요.

저는 이 표현을 volatile 키워드를 사용한 필드 접근 시 내부적으로 lock을 구현해
값의 할당을 항상 보장할 수 있다는 정도의 의미로 해석했습니다.

결국 항상 정확한 값을 얻으려면 Interlock을 쓰든 크리티컬 섹션을 걸든
동기화를 해야만 한다는 것이 결론이었군요.

음... 그러면 이제 volatile을 사용하는 의미가 점점 더 모호해집니다.

이런 동기화 문제가 있다면 처음부터 volatile 사용을 배제하고
배타제어를 하는 것이 더 옳은 방향 같은데

필드 접근에 대해서 volatile만으로 동기화 문제를 완전히 해결할 수 없다면
volatile을 굳이 써야할 이유가 있을까요?
전 그냥 필드를 프로퍼티로 바꿔서 lock을 걸어주는 게 더 안정적일 것 같은데......
(물론 코드가 더 길어지고 동기화 객체도 추가로 필요하겠지만)

volatile의 사용 의미가 더 궁금해 집니다.

기초가 없어서 그런지 부끄럽게도 초보적인 질문만 계속하게 되네요.
[guest]
2013-04-16 01시23분
volatile 은 시스템의 캐시에 보관된 변수를 무효화시켜서 다시 읽어오게 하는 의미와, 컴파일러의 최적화를 방지하는 것에 그 목적이 있습니다. C# 예제는 아니지만, C++ 로 된 다음의 글을 참고해 보세요.

volatile 키워드
; http://www.sysnet.pe.kr/2/0/413
정성태

... 46  47  48  49  50  51  52  53  54  55  56  57  [58]  59  60  ...
NoWriterDateCnt.TitleFile(s)
1177Jeon...10/28/201310526안녕하세요~ 어머니께 물어서 사이트를 찾아왔어요 [2]
1176김태훈10/25/201310313AxWebBrowser에 대해 질문드립니다. [1]
1175서경희10/20/201315312netscape 지원이 되지 않는다는 문구.. [2]파일 다운로드1
1174임동찬10/16/201314120프리징 현상에 대한 고민 [5]
1173김재영10/8/20139914인터페이스에 대해 기초적 질문이 있습니다. [2]파일 다운로드1
1172박진영10/2/201312807웹사이트 연결시 AJAX 어셈블리 오류 문의드립니다. [5]파일 다운로드1
1171링거8/30/201320752ClickOnce 업데이트 문제. [4]
1170임동찬8/28/201312084비동기적 이벤트 핸들링 방법 [2]
1167나종식8/20/201311197win7 에서 LSP 가 DNS Client 에 인젝션 안되는 문제 [6]
1165임동찬8/19/201310500오류 발생시 로깅 문제.. [3]
1164박철8/19/201311148모바일 게임서버를 작성 하려면 무엇부터 시작하여야 하나요? [2]
1163안연준8/2/201310621음... 안녕하세요 ^^ 윈도우즈 폼에 대해서 잠시 물어볼께요 [3]
1162박진영7/23/201390941개의 PC에서 동일사이트 접속제한을 어떻게 하죠? [1]
1161Ji Y...7/12/201311812안녕하세요? 음성인식 관련해서 질문있습니다, [2]
1160이상식7/12/201312198웹서비스 커넥션 풀 오류입니다. [6]
1159김덕성7/4/201320384C# 마샬링 관련 문의입니다 [3]
1157이상식6/26/201314049빌드시 오류인데 원인을 모르겠네요. [2]파일 다운로드1
1156정환나라6/20/201311230In-Process Side-By-Side 동작 원리는 어떻게 되는걸까요? [3]
1155MD워시퍼6/20/201310253안녕하세요. 한가지 궁금한 것이 있어서 문의를 드립니다. [1]
1154it 대...6/13/201313303무선 패킷 스니핑 프로그램 [1]
1153이상헌6/8/201310796죄송합니다;; 또다시 의문점이 생겨 질문드립니다. [1]
1152이상헌6/8/201310469넷두이노 플러스 펌웨어 다운로드가 안되네요;;; [1]
1151황기동6/5/201311272무선 패킷 전송관련 질문 [1]
1147이진권6/2/201311323c# 윈폼 facebook과 연동2 [1]
1144황은영5/29/201315801원격지 서버에서 COM+ 호출이 되지 않습니다. [7]
1143김선희5/28/201316737윈도우 8, 익스플로러 10, 64bit->32bit [1]
... 46  47  48  49  50  51  52  53  54  55  56  57  [58]  59  60  ...