2013-06-02 3 views
1

추가 스레드에서 WIN32 API를 사용하려고 시도하는 중 교착 상태가 발생했습니다. 프레임 속도를 높이려면 응용 프로그램에 추가 스레드가 필요합니다. 사실은, 그러나, 나는 교착 상태를 얻을 수 있습니다 거의 모든 시스템 기능 :다른 스레드를 사용하는 중 Win32 API 교착 상태가 발생했습니다.

::이 ShowWindow :: MoveWindow :: UpdateWindow

나는이 ShowWindow()는 예를 들어, ShowWindowAsync로 대체 될 수 있음을 알고() 문제를 해결하지만 MoveWindow() 및 UpdateWindow()에는 이러한 대체 방법이 없습니다.

누군가 이러한 문제를 경험 했습니까? 해결책은 무엇입니까?

감사합니다.

+0

이러한 스레드에서 동기화를 사용 했습니까? 세마포어, 뮤텍스? (그들은 서로 다른 데이터에 액세스하고 있습니까?) – Dejan

+0

메인 스레드는 때로는 이유 때문에 'UI 스레드'라고도합니다. UI 작업은 주 스레드에서 더 잘 대기합니다. 비록 이것이 Windows에서 치명적인 것인지 알 수는 없지만. – BlueWanderer

+0

첫 번째 스레드가 메시지를 펌핑합니까? 이 오래된 질문을 참조하십시오. http://stackoverflow.com/questions/770503/movewindow-deadlock –

답변

1

"데드락 (deadlock)"이라는 용어는 아주 특정한 것을 말하며, 두 스레드는 다른 스레드에 의해 잠긴 자원에 대한 액세스를 기다리고 있습니다. 이 사건이 귀하의 사건에서 일어났다는 표시는 없습니까 (또는 있습니까?), 그래서 정확히 당신이 경험하고있는 것은 무엇입니까? 또한 멀티 스레딩을 통해 달성하고자하는 목표는 무엇입니까?

UI를 단일 스레드로 유지하려면 SendMessage() & Co를 사용하여 해당 스레드에 백그라운드 스레드에서 발생하는 모든 이벤트를 알립니다. 또는 타이머를 사용하여 특정 상태 변경 사항을 폴링 할 수도 있습니다. 그런 식으로, 당신은 안전한 측면에 있고 응용 프로그램은 잠글 수 없습니다 (적어도 다른 스레드에서 UI를 사용하지 않기 때문에).

좀 더 정확하려면 창과 모든 하위 창에 대한 메시지 루프를 단일 스레드에 보관해야합니다. 여러 개의 창을 만들고 각각의 창에서 각각의 창을 처리 할 수 ​​있지만 전화를 혼용하지 마십시오. 실제로이 구분은 중요하지 않습니다. 응용 프로그램이 여러 개 (예 : 메시지 상자 또는 다른 대화 상자가 포함되지 않음)를 만들지 않기 때문입니다.

1

참조하는 모든 API 함수는 공통적으로 대상 창에 메시지를 보냅니다 (!). UpdateWindow는 아마도 WM_PAINT를 전송해야하기 때문에 가장 확실합니다. 또한 메시지를 "보냈다"고 대기열에 게시하지 않습니다 (UpdateWindow의 경우 MSDN 설명서에서 명시 적으로이 항목을 명시 적으로 명시하고 다른 항목은 명확하지 않을 수 있음).

또한 일부 창에는 windows에 thread affinity이 나와 있습니다. 다른 말로하면이 창에 대한 메시지는 하나의 스레드에서만 수신/발송된다는 의미입니다. 다른 스레드의 창에 메시지를 보내면 운영 체제는 메시지를 디스패치해야하는지 (즉, 창 프로 시저를 호출해야하는지) 결정하는 작업을 맡습니다. 이 (들어오는 보낸 메시지 발송) 특정 API 호출 중에 발생하는 동안 임의의 메시지 사용하여 창 프로 시저를 호출하는 것이 안전하다고 가정 할 수 있습니다. 관련 시간은 GetMessage 및 PeekMessage * 중에 있습니다.

그래서 윈도우 소유 스레드 (UI 스레드라고도 함)가 정상적으로 메시지를 펌핑하는 경우 수신 된 보낸 메시지도 신속하게 발송됩니다. 귀하의 질문에 그것은 그러나, 귀하의 UI 스레드가 현재 바쁜 것 같습니다. 그런 다음 두 번째 스레드가 상기 함수 중 하나를 호출하면 첫 번째 스레드가 보낸 메시지를 전달할 기회를 제공 할 때까지 차단합니다.

다른 사람들처럼 사용자 인터페이스 코드를 하나의 전용 UI 스레드에 보관하는 것이 좋습니다. 예외는 항상 그렇듯이 규칙을 증명합니다. 또한 좋은 사용자 경험을 위해 창 소유 스레드가 항상 메시지에 응답해야하는 것이 반드시 필요합니다. UI 스레드가 일부 동기화 개체를 기다려야하는 경우 MsgWaitForMultipleObjects가 유용 할 수 있습니다.

* 목록이 완전하지 않을 수 있습니다.

+0

답변 해 주셔서 감사합니다. 불행히도 다른 응용 프로그램에 대한 플러그인을 작성하고 있으므로이 응용 프로그램은 다른 스레드에서 창을 호출하기 때문에 모든 경우를 한 스레드로 유지하는 것이 간단하지 않습니다. –

+0

아키텍처의 세부 사항이 무엇이든 상관없이 테이크 어웨이 메시지는 다음과 같습니다. 창 소유 스레드가 메시지를 펌핑해야합니다. 그렇지 않으면 UpdateWindow와 같은 API를 호출 할 수 없습니다. 물론 WM_APP의 특정 메시지를 정의하여 윈도우의 크기를 조정하고 대기열에 게시하도록 할 수 있습니다 (필자는 그러한 디자인이 바람직하지 않다는 뜻은 아닙니다) –