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

... 31  32  33  34  35  36  37  38  39  40  41  42  43  [44]  45  ...
NoWriterDateCnt.TitleFile(s)
4745힘찬도약7/27/201612029.NET 자식창 데이터를 부모창에 전달시 오류 질문드립니다. [4]파일 다운로드1
4744변찬연7/27/201611765안녕하세요 그 edge를 이용하는 데 조금 불편함이 있어서 문의드립니다 [1]
4743딸랑구아빠7/26/201610657IE 사용 시 인증 정보 계속 보내기? [1]
4741차가워7/20/201612242UWP 에서 COM 참조 불가능한가요? [6]
4740luna...7/19/201612653clickonce manifest 파일 질문 [1]
4739윤똘씨7/19/201612112정말 감동적입니다... [7]
4738닷넷초보7/7/201610998안녕하세요. C#의 개체 전달방식(참조)에 관련해서 질문 있습니다. [3]파일 다운로드1
4737beau...7/6/201613327python embedding 한 c++ 프로그램의 배포에 관해서 질문드리고 싶습니다. [1]
4736spow...7/6/201610192Property Lambda에 대한 심층 분석을 의뢰합니다 [7]
4735힘찬도약7/5/201611337.Net/Web.config에서 MSSQL을 쓰는데, MysqlSiteMap 참조오류 [3]파일 다운로드1
4734spow...6/28/201610913Visual Studio 2015 + Windows Forms 환경에서 컴파일 할 때 드물게 개발환경이 Crash 됩니다 [1]
4733feel...6/15/201611376타 서버로 소스 이전 중 [3]파일 다운로드1
4732구봉근6/14/201610129안녕하세요 [1]파일 다운로드1
4731초급개발자6/7/201612664Windows Form Application는 사라질까요? [2]
4730김시현6/4/201610734책으로 공부하던 도중 생성자에 대해서 궁금한게 생겼는데 혹시 답변좀 해주실수 있나요? [1]
4729Jeah...6/3/201612186C#.Net 프로그램에서 C++로 만들어진 dll 파일 이용관련 문의 하나 드립니다. [3]
4727링거5/30/201610832WPF MediaElement 파일 실행 후 삭제시 오류 문의 [1]파일 다운로드1
4728링거5/30/201611209    답변글 [답변]: WPF MediaElement 파일 실행 후 삭제시 오류 문의 [2]파일 다운로드1
4726spow...5/25/201610653덧글을 달고 나서 F5를 눌렀을 때 똑같은 덧글이 달리는 현상 고쳐주세요 [4]
4725Futu...5/23/201611116책 잘보고 있습니다. Task관련 질문을!!! [1]
4724학생15/23/201612398웹소켓과 소켓 관련해서 질문 드립니다. [2]
4722지나가던...5/15/201614223Part 3 pdf파일 그림 재수정 문의 [1]
4723지나가던...5/16/201611472    답변글 [답변]: Part 3 pdf파일 그림 재수정 문의 [1]
4721김종희4/30/2016116323D 시뮬레이션 개발 [1]
4720DC4/29/201611029C# 6.0 델리게이트 인스턴스화 관련 질문~ [2]
4719이민구4/29/201611971[시작하세요! C# 프로그래밍] 4.5.1.6 열거형 마지막 예제 질문입니다. [4]파일 다운로드1
... 31  32  33  34  35  36  37  38  39  40  41  42  43  [44]  45  ...