Microsoft MVP성태의 닷넷 이야기
Parallel.For 에서 동기화문제에 관한 질문입니다. [링크 복사], [링크+제목 복사]
조회: 13749
글쓴 사람
초록물꼬기
홈페이지
첨부 파일
[sync.png]    

안녕하세요, C#을 열심히 공부하고 있는 초록물꼬기라고 합니다.

멀티쓰레딩을 공부하다가 예전에 얼핏 보았던 Parallel Class 를 한번 심도있게 공부해보고자 하는데 도저히 이해를 못하는 부분이 있어서 도움을 청하고자 질문을 드립니다.

일단 질문드릴 간단한 소스코드를 써보겠습니다.

            int n = 0;

            Parallel.For(0, 100, (i) =>
            {
                n++;
                Console.WriteLine(n);
            });

Parallel.For 가 멀티쓰레드로 이 코드를 돌린다고 처음 알았을 때 당연히 n 에 대한 동기화 문제가 발생할거라고 생각했습니다.
하지만 몇번을 돌려도, 중간 인자를 10000으로 늘려도 동기화 문제는 발생하지 않았습니다.

이부분에 대해서 좀 찾아본 결과 Data Parallelism 에 의해 대량의 데이터에 대해 CPU에게 적당히 일감을 나눠준다고 하는데..(http://www.csharpstudy.com/Threads/parallel.aspx)
일단 MSDN 에서도 스레드로부터의 안정성을 All public and protected members of Parallel are thread-safe and may be used concurrently from multiple threads. 라고 명시한 걸로 봐서
(https://msdn.microsoft.com/ko-kr/library/system.threading.tasks.parallel(v=vs.110).aspx)
따로 동기화를 해줄 필요는 없구나! 싶었습니다.
사실 개개의 Thread 에 lock 을 걸어야 한다면 멀티코어의 이점이 엄청 사라질 수 있으니 당연히 장치는 해 두었을거라고 생각합니다.

하지만 중간에 Sleep 를 넣으면.. 즉

            int n = 0;

            Parallel.For(0, 100, (i) =>
            {
                Thread.Sleep(500);
                n++;
                Console.WriteLine(n);
            });

이 코드에서는 n 을 출력한 가장 큰 값이 98 ~ 101 까지 다양했습니다. (제 CPU가 4코어 하이퍼쓰레드라 그런지 값은 8개씩 나옵니다)
즉 동기화 문제가 발생했다는건데(첨부파일 참조)

악보 재생을 Parallel.Invoke() 를 이용해서 하려고 했는데 음악의 속도(BPM)에 따라서 Sleep 는 필연적으로 사용해야 하기 때문에 굉장히 망설여지고 있습니다..

혹여나 제가 MSDN 문서에 대해 좀 잘못 이해하고 있는것 같기도 한데.. 위의 동기화 문제는 왜 발생하게 되는걸까요?








[최초 등록일: ]
[최종 수정일: 1/6/2016]


비밀번호

댓글 작성자
 



2016-01-06 08시52분
[초록물꼬기] 질문 드리고나서 나름 연구해 보았습니다.

1. lock 을 걸어서 동기화를 해보면 어떻게 되는지 돌려보았습니다
 => 동기화가 잘 되는 것을.. 게다가 순서까지 정확히 잘 나오는 것을 볼 수 있었습니다.

2. 쓰레드들끼리 돌아가는 사이에 발생할 수도 있을거라 생각하고 (조금 의미없을지도 모르는)구분선을 생성해주는 메인스레드와 같이 돌렸는데 의외로 처음부터 동기화 문제가 발생하기도 하였습니다.
 => http://mitssi.ncity.net/sync2.png

3. Parallel 이 동기화해주는 원리는 lock 을 거는게 아닐 수도 있을거라 생각하고 혹시나 중복으로 실행하는 쓰레드가 있는지 확인해보기 위해 아래 코드를 실행해 봤는데 마지막 부분에 와서 중복으로 실행하는 부분을 어떤 원리인지는 몰라도 실행은 하되 결과는 적용시키지 않는 것을 볼 수 있었습니다.
 => http://mitssi.ncity.net/sync3.png

4. 조금 흥미로운 점은 3번에서 1000번까지 돌려도 Warning 은 마지막에 가서야 조금씩 발생했지만 3번에서 Sleep 주석을 풀고 1500정도로 맞추면 처음부터 Warning 이 많이 발생한다는 점이였습니다.
게다가 소스코드가 조금 늘어나서 그런지 가끔가다가 알 수 없는 deadlock 도 발생하여 cntl + c 를 한번 누르니 풀려나서 프로그램이 또 실행됩니다.
 => http://mitssi.ncity.net/sync4.png

이상 제가 나름 이해해보려고 노력한 부분입니다 ㅠㅠ (확실한 정답은 아직도 잘 모르겠네요)
[guest]
2016-01-07 12시27분
[ryujh] 안녕하세요. 본문 중에

'악보 재생을 Parallel.Invoke() ...' 로 하는 이유를 모르겠습니다. 악보 재생이 병렬과 관계가 있나요?
[guest]
2016-01-07 12시40분
MSDN의 스레드 안정성은 해당 메서드와 그 내부에서 관리되는 데이터들에 대한 것입니다. 외부의 데이터는 대상이 아닙니다. 가령 Thread.Start도 thread-safe이지만 그 내부에 있는 전역 변수의 값을 thread-safe하게 다루지는 않는 것과 같습니다. Console.WriteLine(n);이 추가되었을 때 동기화 문제가 발생하지 않았던 것은 살펴봐야겠지만, 그건 운좋게 얻은 부수효과일뿐 어쨌든 안전하게 동기화는 해야 합니다.
정성태
2016-01-07 01시31분
[초록물꼬기] @ryujh 아니요! 꼭 병렬로 해야하는 것은 아닙니다. 현재에는 병렬로 안하고 있는데 약간의 랙(?) 같은게 느껴져서 병렬로 해보면 어떨까 싶어서 그렇습니다 ^^
https://youtu.be/RbvFC4d9G7U 여기서 보시면 여러개의 악기가 같이 연주되기 때문에 이 부분을 병렬로 하면 좀 더 자연스럽게 흘러가지 않을까 했습니다.
[guest]
2016-01-07 01시33분
[초록물꼬기] @정성태 아..!! 외부 데이터는 대상이 아니였군요. Thread.Start도 thread-safe 라는 말씀에 확 와닿았습니다. 감사합니다 ^^
[guest]
2016-01-07 01시35분
[초록물꼬기] int n = 0;

            Parallel.For(0, 10000, i =>
            {
                n++;
            });

            Console.WriteLine(n);

으로 했을 때 동기화 문제가 발생하게 되네요. 답변 감사드립니다~~
[guest]
2016-01-07 01시44분
마지막 덧글의 코드가 좀 이상하군요. ^^ 다음과 같은 식으로 확인해야 맞습니다.

        var result = Parallel.For(0, 10000, i =>
        {
            n++;
        });


        while (result.IsCompleted == false) // 병렬 작업이 끝날 때까지 대기
        {
            Thread.Sleep(1);
        }

        Console.WriteLine(n);
정성태
2016-01-07 01시51분
Simple Midi Player using WPF("https://youtu.be/RbvFC4d9G7U") 프로그램 직접 만드신 건가요? 와~~~ 대단하시네요. ^^ 멋진 프로그램입니다.
정성태
2016-01-07 02시08분
[ryujh] 프로그램 잘 봤습니다. 고생 많으셨습니다.

악보 재생이라면 오선마다 악기 하나씩이니 애드립카드의 컴포저처럼 악기별 동시 연주하는 것으로 보면 될까요?

그렇다면 하나의 오선의 연주는 스레드 하나로 순차적으로 실행 (음표 그리는 스레드와 오선그리는 스레드는 별도)

오선마다 스레드는 parallel 반복하는 것이 아니고 시작을 동시에 하고 연주 끝날 때 까지 그 스레드에서 연주나 음표 그리는 스레드를 별도로 두는 것입니다.

컴퓨터 타이머와 스레드 내에서 동기화가 필요할 것 같습니다.

참고하십시오.
[guest]
2016-01-07 02시19분
[초록물꼬기] @정성태 아이고 감사합니다 과찬의 말씀이십니다 ㅠㅠ.. 문제가 많은 프로그램입니다.
수정해주신 코드 보고 또 배웠습니다. 포어그라운드에서 그냥 출력하고 끝날수가 있겠네요.

나름 인터페이스나 클레스 설계라던지.. 굉장히 힘들게 고심하여 MVVM 으로 만들었지만 결과적으로는 이번에도 실패했습니다..
C#의 가비지 컬렉터를 너무 믿지 말라는 말이 너무 와닿네요. 음표를 삭제하고 추가하는 작업을 계속 할 때 삭제한 음표 GUI 덩어리가 일부 남아있는게 계속 쌓여 메모리 릭을 발생시키는데 ㅠㅠ
GUI 덩어리 설계에서 실패한 듯 합니다.. 한번 갈아 엎어서 아예 음표, 코드, 커맨드 들을 IEnumerable 을 상속하여 정말 관리하기 쉽게 만들어보려고 합니다.

집필하신 책 항상 잘 읽고 있습니다. 훌륭한 책 써주셔서 감사합니다 ^^
[guest]
2016-01-07 02시28분
[초록물꼬기] @ryujh 조언 감사합니다 ^^
악기별 동시 연주가 맞습니다.
컴퓨터 타이머와 스래드 내의 동기화 부분에서 많은 고생을 했습니다.
앞으로 더 잘 설계해야 좀 더 부드러운 재생이 가능하겠죠!
연주하는 함수는 이번에 갈아엎을 때 말씀하신 부분 참고하여 설계해보도록 하겠습니다
[guest]

... [46]  47  48  49  50  51  52  53  54  55  56  57  58  59  60  ...
NoWriterDateCnt.TitleFile(s)
3695Bere...2/15/201612844호출당한 메서드가 호출한 메서드를 알 수 있는 방법이 일반적인 방법 말고도 있을까요? [2]
3693조영준2/11/201613494UWP 앱을 만들고 있습니다. 죄송하지만 몇 가지 질문 드립니다. [4]
3692후배2/8/201612410html/css/js를 이용한 winForm의 UI표현이 가능 한가요? [3]
3690김대석2/5/201610904문의 드립니다. [2]
3687허재영2/3/201612501web api 보안관련 질문입니다. [2]
3685조진우2/1/201612433메인 응용 프로그램에서 DLL을 실시간으로 접근하여 사용하는데 이것을 모니터링 할 수 있을 까요? [1]
3684나그네1/27/201611760안녕하세요..wcf 관련하여 질문있습니다. [4]파일 다운로드1
3683김태형1/25/201612062 안녕하세요 저작도서를 구매하려는데 한가지 문의 사항이 있어서 질문드립니다. [1]
3681이영균1/8/201614649IE브라우저 추가기능관리의 항목을 사용함으로 c#코드로 변경을 하려고 합니다. [8]
3680후배1/6/201614880추천할만한 소켓 라이브러리 있으신가요? [2]
3679초록물꼬기1/6/201613749Parallel.For 에서 동기화문제에 관한 질문입니다. [11]파일 다운로드1
3678김민우1/3/201612182IHS 오류에 대한 질문입니다. [2]파일 다운로드1
3677초록색우산12/31/201513736HTTP 통신 - WebClient 이용시 한글깨짐 현상 발생 [2]
3676서정열12/31/201512597안녕하세요 WebService SoapExtensionImporter 에 대해서 질문드립니다. [3]
3675차가워12/30/201511665윈폼, 폼인폼 상황에서 하위컨트롤 포커스 문제 [1]
3673Sung...12/24/201512724UWP예외 발생 : 'System.Runtime.InteropServices.COMException'(mscorlib.ni.dll) 해결방법 [2]
3672Sung...12/23/201511970global::System.Diagnostics.Debugger.Break();가 노랗게 표시될시 [2]
3671이상준12/22/201516127한글 키보드 입력에 대해서 질문이 있습니다. [3]
3670Sung...12/18/201512900UWP 주기적으로 신호를 보내고 클라이언트에서 신호가 오면 받는 프로그램을 하려고 합니다. [5]
3669다비드12/18/201511191인터넷 임시파일 삭제 관련 질문. [1]
3668김치사발면12/16/201510652템플릿이 자꾸 초기화? 되버리네요 [1]
3667김치사발면12/15/201510569템플릿 설정 추가 질문 [1]파일 다운로드1
3666노태현12/15/20159980사용자별로 권한을 주고 볼 수 있는 데이터를 제한하려면 어떤 방법으로 접근하는게 좋을까요? [2]
3665김치사발면12/14/201513082C# 템플릿 설정이 이상해요ㅜㅜ [3]파일 다운로드1
3664KuLu12/10/201510394멀정하던 사이트 중 일부메뉴가 응답없음이 되어버립니다. [3]
3663Sung...12/10/201511741UWP 서버 프로그래밍 작업 중 [5]
... [46]  47  48  49  50  51  52  53  54  55  56  57  58  59  60  ...