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

... [61]  62  63  64  65  66  67  68  69  70  71  72  73  74  75  ...
NoWriterDateCnt.TitleFile(s)
1091김대경9/20/201210552    답변글 [답변]: windows2008 에서 ActiveX 사용 시 문제점. [2]파일 다운로드1
1081Seon...8/20/201212879WCF 파일 업,다운로드 문제 [2]
1080배동선8/13/201211667정품 라이센스 인증 개발에 대해 조언을 구하고 싶습니다 [4]
1079송준호8/11/20129674basicHttpBinding stream 전송에 관하여 질문드립니다. [1]
1078Ho S...8/10/20128853윈도우폰 지도 구현에서 ㅠㅠㅠ 질문드립니다. [1]파일 다운로드1
1077한우주8/6/201211783웹서비스 호출 후 세션 유지하기 [1]
1076이성환8/2/201211278dynamic 변수 할당은 도대체 어디에???? [1]
1073pass...7/24/201211130c# 으로 만드는 음성인식/TTS 프로그램에 관련해서.. [3]
1072일반인7/23/201213388rss 만드는 방법 알려주실 수 있으신가요? [5]
1069임경훈7/20/201214108아래와 같은 오류후 IIS가 다운되는 현상이 발생합니다. [1]
1068신호철6/15/201213443ClassLibrary COM+ 등록 안되는 현상 [2]
1067김은주6/14/201222826소스세이프 사용시 pfx 파일 빌드 실패 [3]
1066너무초보6/3/201210026안녕하세요! 디렉토리 삭제 오류 질문 좀 드립니다. [4]
1065이성환5/23/201211786Assembly.LoadFrom Assembly.Load 의 차이점이 궁금합니다. [2]파일 다운로드1
1064푸우5/21/201210627GPU 디바이스 재시작시 WPF + .NET 3.5 기반 어플리케이션 UI 문제 [2]
1063발코더5/20/201210763귀신 곡할 상황 질문입니다. [3]
1062김규덕5/12/201210895ffmpeg 관련 조언 구합니다. [2]
1061Dave5/11/20129621언제 스크린 캡쳐 하시나요? [1]
1058정재훈5/11/201211549c#으로 동영상에 로고를 삽입하는 기능을 구현중입니다. [3]
1057전남진5/1/201210593** 몇일째 고생하다가 웹 검색을 통해 알게되어 질문드립니다.. 초보 질문이긴하지만 도움 부탁드려요 [2]
1056안현수5/1/201212343listview 와 웹파싱에관해 질문드립니다 [1]파일 다운로드1
1055이성환4/30/201210488WPF FramworkElement의 이벤트를 가져오고 싶습니다. [3]
1054정웅모4/20/20129998안녕하세요 [1]
1053폭풍코딩4/19/201210340스마트클라이언트 ctrl-c 복사가 작동하지 않습니다. [1]
1052에슈리온4/17/201226068ClickOnce 배포시 클라이언트의 설치경로를 지정할 수 없나요? [1]
1051최정수4/10/201213178WCF 클라이언트 비정상 종료 관련 [1]
... [61]  62  63  64  65  66  67  68  69  70  71  72  73  74  75  ...