Microsoft MVP성태의 닷넷 이야기
volatile 키워드 관련 질문입니다. [링크 복사], [링크+제목 복사],
조회: 10723
글쓴 사람
이성환 (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
정성태

... 31  32  33  34  35  36  37  38  39  40  41  [42]  43  44  45  ...
NoWriterDateCnt.TitleFile(s)
4801spow...2/3/201710269C#의 참조 동작관련하여 아이디어 문의 드립니다 [4]
4800오세운2/1/201714340C# 에서 C++ DLL임포트 질문입니다. [2]
4798guest1/29/201711686picturebox의 image.dispose [1]
4797김철환1/13/201711632책에 관한 질문입니다 [3]
4796Bere...1/13/201711740++ 후위연산자와 = 을 함께 사용할 때 생성되는 IL 코드 관련... [2]
4795김철환1/11/201712844이벤트 부분을 읽고 있는데 이해가 안되서 질문합니다.. [11]
4794김철환1/10/201710137안녕하세요 c# 6.0 책을 구매한 사람인데요 [3]
4793장준영1/7/201712156안녕하세요 c언어 처음 공부해보는 학생입니다 [4]파일 다운로드1
4792김재영1/4/201713176소스코드 공개 전 성태님의 의견을 듣고싶습니다 [3]
4791C#초보12/28/201612976비동기 소켓 close시 ObjectDisposedException 문제점 질문 있습니다.. [1]
4790미나리12/24/201613218파워포인트 쇼 제어 SimpleHttpServer.cs 작동문제 [4]파일 다운로드1
4789김솔지12/21/201612045프린트 시, 프린트하는 파일의 파일명 구하는 부분에 대해서 질문드립니다. [1]
4788짜두12/19/201611784Visual Studio 2015 에서 msbuild 12 사용 [5]
4787guest12/18/201613586VLC라이브러리에 대해 아시나요? [3]파일 다운로드1
4785Hyou...12/16/201613703WPF 개발 시 MVVM 프레임워크 사용 [2]
4784ds12/15/201610358문의 드립니다. [2]
4783후배12/13/201611962MemoryStream에 관한 질문 입니다. [5]
4782김형민12/6/201610294[ C# 6.0 ] 126p 오타인가요? [6]
4781질문자11/29/201610413ms워드 저장 오류 [1]
4780최진11/28/201614861안녕 하세요 빌드 관련해서 질문드립니다 꾸벅 [4]
4779손니11/28/201611215안녕하세요 질문하다 드려도 될까요 [3]
4778김상호11/25/201610736재귀호출->비재귀호출 [2]파일 다운로드1
4777권오영11/12/201613001아래 질문 상세 소스전체입니다.. [3]
4776권오영11/11/201610889제가 이클립스를 공부중인데..이상한것을 찾았습니다.. [2]
4775이성환11/11/201614374안녕하세요. SnapsToDevicePixels 질문입니다. [5]파일 다운로드1
4774popo11/10/201610991.net SSL통신 관련 질문 드립니다. [1]
... 31  32  33  34  35  36  37  38  39  40  41  [42]  43  44  45  ...