|
성시완 님이 쓰신 글 :
: 메인 폼에 에디트 컨트롤이 하나 있고
: 쓰레드를 생성해서 이 에디트 컨트롤에 숫자를 증가시켜 주고 있습니다.
: 물론 이 쓰레드는 제가 만든 것으로 메인 쓰레드랑은 다르지요.
: 쓰레드 내에서 숫자를 증가시키고 메인 폼 포인트를 갖고 있어서 에디트 컨트롤에 직접 업데이트 해줍니다.
: 그런데 질문란에 보니까 폼에 업데이트 할 때 Synchronize함수 를 쓰라는데
: 꼭 이걸 써야 하나요. 딱히 문제는 없어 보이는데 아시는 분 답변 좀 해주세요.
: 지금은 문제가 없지만 나중에 혹시 문제가 될 것 같아 불안하네요.
: 감사합니다.
이 부분때문에 어려움을 겪고 있으신 분들이 생각보다 주위에서 많은 것 같네요.
모든 Graphic User Interface를 가진 시스템들은 그래픽라이브러리를 처리하는 이벤트 핸들러라는 놈을 가지고 있습니다.
그래픽 UI 에 관한 모든 일은 사실 이벤트 핸들러의 허락 없이는 맘대로 접근하면 안됩니다.
(쉽게 생각하면 이놈은 교통 경찰 같은 놈입니다.
교통 경찰이 한눈 팔 경우, 몰래 무단 횡단을 할 수 는 있겠지만, 최악의 경우 차에 치이거나, 걸려서 딱지 끊기거나 하겠죠.
어쩌다 성공해서 무사히 길을 건널 수 있겠지만, 늘 성공할걸 기대하면 안됩니다. ㅎㅎ.)
이게 최우선으로 처리하는 쓰레드가 각종 입력 이벤트를 처리하고, 그 결과를 화면에 드로우하는 기능입니다.
가장 기본이 되는 이 쓰레드를 UI 쓰레드 또는 메인 쓰레드라고 합니다.
화면이 무효화되는 순간 (변경이 되거나 다시 그려야 하는 경우) 그래픽 라이브러리(메모리에 있는 화면 그림)를 다시 드로우하고
화면을 업데이트 해야 되는데, 이게 방해를 받으면 화면이 하얗게 되면서 응답없음 뭐, 대충 이런 상태가 되거나,
사용자 반응에 응답을 제대로 하지 않거나, 매우 느리게 느껴지게 됩니다.
플랫폼에 따라, 예외 메시지를 출력하고 그냥 종료되는 경우도 있습니다 (안드로이드 플랫폼).
윈도우에서도 종종 경험을 해 보셨을 겁니다.
일단, 사용자에게 가장 보이는 부분이기 때문에 프로그램이 죽었다고 오해를 받지 않으려면 그리는 기능에 충실해야 됩니다.
즉, UI 쓰레드에 무한루프를 일부러 만들면 그거 처리하느라 WM_PAINT 에 응답을 못하게되면서 그리는 기능을 방해받게 됩니다.
전형적으로 그런 현상이 되는 겁니다.
만약, 사용자가 별도의 쓰레드(워커쓰레드 라고 합니다)를 만든 후, 메인쓰레드의 어떤 기능을 직접 접근해서 위와 유사한 상황을 만든다면, 동일한 문제가 발생하겠죠. 다른 말로 하자면 어떠한 상태이든, 메인 쓰레드의 그리는 기능에 개입하면 안된다는 것입니다.
그것은, 그래픽라이브러리에 그리는 기능은 메인쓰레드의 고유 권한이고 이것은 공유자원이기 때문에 어떤 형태로든 동기화를 하지 않으면 안되는 것입니다.
그래서
1) 동기화를 할 경우, 메인쓰레드가 그리거나 그리려고 하면 기다렸다가 접근하면 되고,
2) 그게 싫으면 큐에 메인쓰레드가 여유있을때 처리해 달라고 요청을 하는 겁니다.
PostMessage를 이용합니다. SendMessage는 큐없이 직접 접근을 하기 때문에 위의 문제를 여전히 일으킬 가능성이 있습니다.
이 내용은 안드로이드 프로그래밍도 똑 같습니다.
워커쓰레드에서 메인쓰레드에 접근을 하려면 큐를 이용해 처리를 요청해야 합니다.
그런데, 언젠가 누군가가 직접 접근하는 코드를 짰고, 안드로이드 플랫폼의 동작 상태는 매우 렌덤하게 뻗어 버립니다.
지금 문제가 없어 보이시는 건, 그냥 우연일 뿐입니다.
워커쓰레드에서 접근하고 있을때, 다행히 메인쓰레드의 UI 관련 콜백 이벤트가 겹치지 않았을 뿐이죠.
그것이 또한 우연히 서로 주기성을 가진다면, 문제가 없는 듯 보이기도 합니다.
그런데, 공학이란 건 그런 우연을 기대하고 할 수 있는 것이 아닙니다.
언제나, 누구나에게도 같은 결과를 재현할 수 있어야만 하는 걸 공학(또는 과학) 이라고 말합니다.
때문에 기본 개념을 이해하는 것이 매우 중요하다고 생각합니다.
어쨌든 구조상 어떤 플랫폼을 만들어도 저 상황은 다른 방법이 딱히 없을 듯 합니다.
이해하시는데 도움이 되시길 희망합니다.
|