2013-01-07 2 views
0

비슷한 언어가 여기에 적용되지만 C#으로 작성한 응용 프로그램이 있습니다.멀티 스레딩 모범 사례

응용 프로그램은 다양한 UDP 및 TCP 소켓을 통해 수신되는 데이터를 기반으로 실시간으로 양식의 창에 그래픽 장면을 그리는 작업을 수행합니다. 각 UDP 및 TCP 연결은 자체 스레드를 사용합니다. 이러한 스레드는 메모리의 다양한 객체를 수정하여 그래픽 디스플레이를 수정합니다. 또한 사용자 이벤트 (버튼 클릭 등)를 수신 할 수있는 사용자 인터페이스 스레드가 있는데,이 객체 스레드는 동일한 객체 및 디스플레이를 수정합니다. 마지막으로, 나는 또한 같은 개체와 디스플레이를 수정하는 자신의 스레드를 실행하는 많은 타이머를 가지고 있습니다.

수정되는 메모리의 개체는 약 15 개의 서로 다른 클래스로 구성됩니다.

모든 것이 꽤 안정적으로 작동하지만, 다른 클래스로 수정되는 모든 클래스가 서로 다른 스레드로 수정되면 동기화 잠금이 많이 추가되었습니다. 각 클래스를 개별적으로 살펴보고 둘 이상의 스레드가 어떤 메모리를 변경할 수 있는지 확인해야했습니다.

이 상황에서 아주 쉽게 보이는 부분이 있습니다. 어딘가에 동기화를 추가하는 것을 잊어 버리는 것입니다.

다른 사람들이 내가 한 것처럼 구현할지, 아니면 좀 더 우아한 방법이 있는지 궁금합니다. 아마도 클래스 A의 수정을 모두 자체 스레드 또는 다른 것에 넣는 것이 어쩌면 궁금합니다.

(추신 : 처음에는 일이 잘 풀리지 않으면 여기에서 질문하는 것이 두려워요.하지만 내 질문이 너무 분명해서 생각하지 않습니다. 어느 쪽이든.; o)

답변

1

나는 이것에 대해 솔직한 대답이 없다고 생각한다.

비슷한 상황을 처리하기 위해 다른 디자인을 변경하는 데 도움을주었습니다. 가장 일반적으로 사용되는 기술 중 하나는 더 나은 추상화를 도입하는 것입니다.

예를 들어 사용자 맵과 활성 사용자 세트에 대한 잠금을 가지고 있지 않고 스레드가 수동으로 잠금을 획득하도록하는 대신 사용자가 포함 된 맵과 활성 사용자가 포함 된 다른 세트를 업데이트해야하는 다중 스레드가 있고, User map과 Active User Set가 포함 된 추상화 호출 인 UserRepository를 소개 할 것을 제안합니다. UserRepository는 다른 사람들이 UserRepository를 조작 할 수있는 의미있는 방법을 제공합니다. 잠금은 호출자가 명시 적으로 대신 UserRepository의 메서드에서 획득합니다.

과거의 경험에 비추어 볼 때 위의 예와 같이 더 나은 디자인을 사용하면 복잡한 동기화의 80 % 이상을 크게 단순화 할 수 있습니다.

다른 기술도 가능합니다. 예를 들어 업데이트가 비동기 적으로 수행하는 것이 좋으면 스레드가 리소스를 직접 업데이트하는 대신 명령 객체를 만들고 생산자 - 대기열에 넣고 전용 스레드에서 업데이트를 수행 할 수 있습니다.

가끔 잠금을 적게 처리하는 것이 훨씬 쉽습니다. 예를 들어 여러 리소스를 업데이트 할 때 각 리소스에 대해 하나의 잠금을 사용하는 대신 업데이트를 전체 동작으로 볼 수 있으며 스레드 간의 조정에는 하나의 잠금 만 사용합니다. 물론 경합은 증가하지만 경합은 큰 문제는 아니지만 유지 보수가 필요한 경우가 있습니다.강력한 답변을 너무 많이

+0

감사 :

난, 난 그냥 (P 일) 내 이전의 경험의 일부를 공유하고 비슷한 상황에 대처하기 위해 다른 방법을 많이가있다 생각합니다. 이것은 주제에 대한 정말 좋은 토론입니다. – vmayer