Microsoft MVP성태의 닷넷 이야기
volatile 키워드 관련 질문입니다. [링크 복사], [링크+제목 복사]
조회: 10633
글쓴 사람
이성환 (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)
1303김동진8/7/201411241vmware환경에서 Guest IP를 192대역으로 받을 수 있는 방법은 없을까요~? [3]
1302김문경7/31/201410442스마트클라이언트 오라클 연결 [1]
1314이재균8/20/201410496    답변글 [답변]: 스마트클라이언트 오라클 연결
1300아로스7/28/201423332c# 인터넷 임시 파일 삭제 문의 [12]파일 다운로드1
1299서동원7/28/201411934안녕하세요. 혹시 Internet_Zone과 관련된문제인가 해서 질문드립니다. [1]
1298(non...7/25/201417299(글쓴이의 요청으로 삭제합니다.) [15]
1295서동원7/22/201413035안녕하세요. 스마트클라이언트에 대해 질문드립니다. [2]파일 다운로드1
1294(non...7/20/201411438(글쓴이의 요청으로 삭제합니다.) [2]
1293VS20...7/20/201412006VS2013 Ultimate에 Windows Phone 프로젝트 템플릿 추가 방법 문의 [1]파일 다운로드2
1292(non...7/20/201410729(글쓴이의 요청으로 삭제합니다.) [2]
1291zino7/16/201411334chromium 배포본 만들기~ [1]
1290(non...7/13/201412487(글쓴이의 요청으로 삭제합니다.) [3]
1288박주만7/8/201421672C# 서비스 기반 데이터베이스(mdf) & InstallShield Limited Edition 설치 및 배포 [2]파일 다운로드1
1287김용환7/8/201419684오라클 db 사용관련 문의입니다. [4]파일 다운로드1
1286C#조으다7/8/201410646WebBrowser 공유기 관리 웹 페이지 인증 [3]
1285C#조으다7/5/201410990IE DocumentComplete 이벤트가 발생되지 않습니다. [2]
1284(non...7/4/201411109(글쓴이의 요청으로 삭제합니다.) [3]
1283김영대7/3/201414225안녕하십니까 정성태님 죄송하지만 SmartClient 에 관한 질문이 있습니다. [9]
1282(non...7/2/201411087(글쓴이의 요청으로 삭제합니다.) [2]
1281(non...7/1/201412172(글쓴이의 요청으로 삭제합니다.) [4]
1280동동이6/25/201411387안녕하세요. ocx의 비동기 또는 쓰레드에서 호출 [1]
1279(non...6/23/201411471(글쓴이의 요청으로 삭제합니다.) [17]
1278이상식6/19/201412697.net DLL 내 자바스크립트를 수정 또는 재정의 할 수 있을까요? [3]
1277김솔지6/18/201410392silverlight에서 datagrid, listbox질문이여 [2]
1276정우석6/16/20149910쿠키 [1]
1274김솔지6/10/201414401배포 페이지 url을 얻고 싶습니다. [8]
... 46  47  48  49  50  51  52  53  [54]  55  56  57  58  59  60  ...