특집기사:다중 Display에 관하여

위클립스
이동: 둘러보기, 찾기
Article.png 특집기사 정보
Jeeeyul.jpg
저자 이지율

이 문서는 SWT 계약을 잘 준수한 경우에도, 다중 Display의 사용이 문제가 되는 경우를 소개한다.

[편집] 개요

윈도우즈용 SWT는 다중 Display를 허용한다. 그러나 MAC OSX등과 같은 다른 운영체제는 그렇게 할 수 없다. Cocoa 프레임워크가 첫번째 스레드만 UI스레드로 허용하기 때문이다. 이런 이유로, 가능한한 다중 Display는 사용하지 않는 것이 좋다.

그럼에도 불구하고 성능상의 이유로 다중 Display를 써야할 경우가 생긴다. 예를 들면 백그라운드 스레드에서 이미지를 생성하거나 가공하는 경우이다. 만약 하나의 UI스레드로만 이러한 작업을 처리하면, UI동기화를 위한 간섭 때문에, 사용자 경험이 상당히 뒤떨어지게 된다.

그래서 나는 다음 코드처럼, Win32에 한하여, 배경 스레드에 Display를 이용하는 테크닉을 종종 사용하곤 했다:

  1. Display ghostDisplay = null; // 배경 스레드에서 사용할 디스플레이
  2.  
  3. Display currentDisplay = Display.getCurrent(); // 현재 스레드가 디스플레이를 소유한 경우(메인 스레드인 경우)라면 얻음.
  4.  
  5. // 현재 스레드에 디스플레이가 없고 플랫폼이 Win32라면
  6. if (currentDisplay == null && Platform.getOS().equals(Platform.OS_WIN32)) {
  7.    try {
  8.       currentDisplay = ghostDisplay = new Display();
  9.    } catch (Exception e) {
  10.       e.printStackTrace();
  11.    }
  12. }
  13.  
  14. // 현재 스레드에 디스플레이가 확보된 경우
  15. if (currentDisplay != null) {
  16.    // Display 를 필요로 하는 비즈니스 로직 수행
  17. } else {
  18.    // 메인 스레드에 동기화 하여 비즈니스 로직 수행
  19.    // 이 경우 작업이 길다면, 메인 스레드는 잠시 멈추게 되어 UI가 무응답 상태가 된다.
  20.    Display.getDefault().syncExec(someJob);
  21. }
  22.  
  23. if(ghostDisplay != null){
  24.    ghostDisplay.dispose();
  25. }

위 코드는 오늘까지 문제점이 발견되지 않은채 잘 작동했으나, 불행히도 그렇지 않음이 증명되었다.

[편집] 문제

나는 이 테크닉을 매우 복잡한 Draw2D 피겨를 아직 자세히 보여줄 필요가 없을 때, 그 크기의 근사치를 미리 계산하기 위해 사용했다.

Draw2D의 피겨 업데이터는 자기자신에게 처음 메시지를 보낸 Display를 캐시해 두고, 이를 이용하여 Figure들을 업데이트 한다. 따라서 위의 코드에 포함된 16비즈니스 로직이, 배경 스레드에서 처음으로 피겨 업데이터를 간섭한 경우, 피겨 업데이터는 엉뚱한 Display를 캐시하게 되고 Draw2D 전체의 피겨 업데이트 매커니즘이 붕괴된다 - 24에서 이 Display가 파기되므로

이 문제는 단 한번이라도 메인 스레드가 먼저 피겨 업데이트 매니저를 사용한 경우, 재현되지 않기 때문에, 원인을 규명하는데도 많은 시간을 허비해야 했다.

[편집] 결론

따라서, 내가 아무리 SWT와의 계약을 잘 준수했다 하더라도, 다른 서드파티 플러그인들 상당수가 Display는 메인 스레드 하나에서만 소유한다라는 가정을 깔고 구현되어 있기 때문에, 문제가 될 수 있다는 것이다.

오늘의 교훈은, 터부시 되는 것은 무조건 피하자라는 것.

이 기사에 대한 의견은 토론 페이지를 통해 나눌 수 있습니다.

개인 도구
이름공간
변수
행위
포탈
탐색
도움
도구모음