들어가며
지난 글에서 QTimer의 동작 원리를 자세히 살펴보면서,
"Timeout" 이벤트 발화 시점에 EventLoop가 점유되어 발생하는 지연 문제를 테스트 코드로 재현해 보았다.
2026.04.09 - [Qt] - QTimer 지연/누락 버그 해결 - EventLoop 점유로 인한 tick 누락 원인과 테스트 코드
QTimer 지연/누락 버그 해결 - EventLoop 점유로 인한 tick 누락 원인과 테스트 코드
들어가며Qt Framework의 최고의 장점은 크로스 플랫폼(Cross-Platform)을 지원하는 풍부한 라이브러리다. 그중에서도 QTimer는 특정 시간마다 반복 실행하거나 시간 관련 기능을 개발할 때 매우 편리하다
prejudice.tistory.com
이전 글의 테스트 코드에서는 EventLoop를 분리하기 위해 "Runner" 인스턴스를 worker 스레드에 넘기는 방법을 사용했다.

여기서 문제는 실제 인스턴스의 위치(taskManager::runner)와 실행되는 스레드(workerThread)가 달라 헷갈린다는 점이다.
이 글에서는 클린 코드 작성을 목적으로 Executor 클래스를 도입하여, 분리된 EventLoop 위에서 동작하는 깔끔한 설계를 만들어 보려 한다.
Command Pattern
Executor 클래스를 고려하기 전에, 유사한 개념의 디자인 패턴인 Command Pattern 을 먼저 살펴보자.
이 패턴의 첫 번째 장점은 "행위자"와 "행동"을 분리하여 의존성을 제거하고 재사용성을 높이는 데 있다.

두 번째 장점은 행동을 호출하는 객체와 행동의 구현을 완전히 분리하는 것에 있다.
Requester는 CommandA / CommandB의 구현 세부 사항을 알 필요가 없어진다.

💡Producer-Consumer Pattern vs Command Pattern
설계 패턴 중 프로듀서-컨슈머 패턴이란, 멀티스테드 환경에서 데이터를 생성하는 Producer와 데이터를 처리하는 Consumer를 큐로 분리하여 데이터를 순차적으로 처리하는 패턴이다.
서로 비슷한 느낌이지만 이 패턴의 핵심 목적은 큐를 통해 비동기 작업을 처리한다는 것에 있고,
커맨드 패턴은 행동을 캡슐화하여 Requester-Behavior를 분리한다는 데에 미묘한 차이가 있다.
Executor 객체를 이용한 Thread 분리
Executor Pattern은 작업의 정의와 실행 주체를 분리하는 패턴이다.
Command Pattern을 예로 들면, Command 역할을 하는 Task 객체와 이를 실제로 실행하는 Executor 객체를 분리하는 구조라고 볼 수 있다.

객체가 분리되면 QObject::moveToThread() 를 사용하여 Executor 객체의 thread affinity를 변경함으로써,
특정 스레드의 EventLoop에서 동작하도록 구성할 수 있다.
즉, Requester가 속한 스레드와 Executor가 동작하는 스레드를 분리할 수 있다.
이 구조의 장점은 두 가지다.
- "Request"는 작업 실행을 "Executor"에 위임하므로 두 객체 간의 의존성이 감소한다.
- "Task"는 "Requester" 인스턴스 안에 존재하므로 코드 가독성과 일관성이 향상된다.
위에서 살펴본 그림1. TestCode 에 적용하면 다음과 같이 정리할 수 있다.

회고
오늘은 코드를 리팩토링 하며 Executor 구조를 통해 스레드를 분리하고 안정화하는 작업을 진행했다.
포스팅은 설계를 깔끔하게 하는 것을 위주로 작성했지만, 실제 진행 중인 프로젝트에서는 다른 문제가 있었다.
큰 프로젝트 안에서 Task가 Executor 역할까지 담당하면서 main EventLoop 위에서 동작하고 있었고,
특정 시점에 다른 비동기 Slot 처리로 인해 실행 지연이 발생하는 버그를 수정했다.
실제 발생한 버그와 Executor 구조는 전혀 다른 내용처럼 보이지만, 버그가 발생한 배경과 EventLoop와의 관계를 공부하다 보니 자연스럽게 "Executor 구조를 통해 의존성을 낮추는 설계"를 주제로 글을 쓰게 됐다.
포스팅을 준비하면서 개념을 더욱 확실하게 정리할 수 있었고, Command-Behavior 패턴과 Executor 구조는 앞으로도 유용하게 활용할 수 있을 것 같다.
직접 공부해서 다음 글로 정리해 보려고 합니다.
함께 볼만한 글 : 2026.01.23 - [Qt] - Qt Event Loop 동작 원리 정리 ㅡ 타이머, 이벤트, 스레드 까지
Qt Event Loop 동작 원리 정리 ㅡ 타이머, 이벤트, 스레드 까지
들어가며Qt는 크로스 플랫폼 애플리케이션 개발 프레임워크로,동일한 코드로 Windows, Linux, macOS, Embedded Linux 등 다양한 운영체제에서 동작하는 App을 만들 수 있다. QObject, Signal/Event, QTimer 등을 사용
prejudice.tistory.com
함께 볼만한 글 : 2025.12.31 - [개발] - 개발 실무에서 UML을 어디까지 그려야 할까?
개발 실무에서 UML을 어디까지 그려야 할까?
들어가며실무에서 UML을 그려야 하는 상황에 부딪히면 다음과 같은 고민이 생긴다."이걸 어디까지 그려야 하지?", "UML을 잘 그리는 방법이 뭐지?"실무에서 내가 선택한 기준과 작성방법을 정리해
prejudice.tistory.com
'Qt' 카테고리의 다른 글
| QTimer 지연/누락 버그 해결 - EventLoop 점유로 인한 tick 누락 원인과 테스트 코드 (1) | 2026.04.09 |
|---|---|
| QML Stopwatch 구현 따라 하기 - MVVM 구조로 설계한 Qt 아키텍처 (0) | 2026.02.20 |
| Qt6 QML 따라하기 ㅡ 프로젝트 생성부터 C++ 연동까지 (0) | 2026.02.10 |
| Qt QML 내부 동작 원리 이해하기 ㅡ Property Binding, Event Loop, Scene Graph (0) | 2026.02.02 |
| Qt QObject와 moc의 동작 원리 이해하기 ㅡ Signal/Slot과 런타임 리플렉션 (0) | 2026.01.28 |