Microsoft MVP성태의 닷넷 이야기
volatile 키워드 관련 질문입니다. [링크 복사], [링크+제목 복사]
조회: 10603
글쓴 사람
이성환 (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)
5016지누7/19/20187458    답변글 [답변]: ASP.Net Core 를 안드로이드에서 작동하는게 가능한가요?
5014최홍준7/16/20187337Credential Provider Child Window 띄우기 [1]
5013Soul...7/16/20187941HtmlElement 스크롤 문의 [2]
5012황윤하7/13/20188484SMTP 예외처리 관련 질문 [1]
5011guest7/9/201815995c#에서 c++ DllImport 문의 입니다. [1]파일 다운로드2
5010C# 꿈...7/8/20188624C# WebService 에서 질문이 있습니다. [1]
5009C#초보자7/5/20189898[C#] 감시 프로그램을 제작했는데, 작동은 하나 폼이 멈춰버렵니다... [1]파일 다운로드1
5008도와주세요7/5/20189548 리스트 아이템의 타입을 추출해서 다시 재활용하고 싶어요.2 [6]파일 다운로드1
5007도와주세요7/4/201810673리스트 아이템의 타입을 추출해서 다시 재활용하고 싶어요. [1]
5006정환나라7/4/20189666소켓 통신과 쓰레드에 관해 질문드립니다 [4]
5005psh7/4/20188577인용에 관련해 문의 드립니다 [1]파일 다운로드2
5004까오리7/4/20188658iis8.0에서 닷넷1.1을 사용하기 위한 질문입니다. [1]
5002멋쟁이7/2/20188942WPFApp에 관한 초보 질문입니다. [1]파일 다운로드1
5001김학완7/1/20189121시작하세요 C# 7.1 프로그래밍 P53쪽 질문입니다. [2]
5000레몬6/26/201810781안녕하세요 성태님 도움으로 C# 네이버 카페 스팸글 작성되면 삭제되는 프로그램을 만들었는데요..여쭤볼게 하나 있습니다. [3]
4999jt6/21/20188640검색어 입력, 엔터 > 페북 로그인창으로 이동합니다. [4]
4998개발희망6/11/20189590C# 형변환 질문있습니다! [1]
4997초보개발자6/5/201821810C++ dll C#에서 사용하는데 보호된 메모리 오류떠요 한번만 도와주세요ㅜ [1]파일 다운로드1
4996swc6/5/201810061현업에서 주로 사용하는 DB업데이트 방법 질문입니다. [1]파일 다운로드1
4993학생6/3/20188233질문 드립니다 [1]
4991최진안5/24/20188226Credential Provider 질문 [2]
4990heyg...5/21/20189115Sybase Adaptive Server Anywhere 6 버전에 대한 질문입니다. [9]
4989강한음5/18/201811347clickonce 배포 후 실행 무응답 [4]
4988C#7....5/17/20188127dynamic 키워드를 사용한 객체 핸들링에 대해서 여쭤보려고 합니다. [1]
4987포플러5/14/20189126닥터왓슨 로그 - c0000005 (액세스 위반) 분석 부탁드려도 될까요? [2]
4986익명5/14/201810836비주얼 스튜디오 wpf 프로젝트에서 어떻게 하면 exe파일과 실행에 필요한 파일들을 분리해서 정리해서 디렉토리로 묶을 수 있을까요? [4]
... 31  32  33  [34]  35  36  37  38  39  40  41  42  43  44  45  ...