Qt의 멀티스레딩 기술

Qt는 스레드 작업을 위한 많은 클래스와 함수를 제공합니다. 다음은 Qt 프로그래머가 멀티스레드 응용 프로그램을 구현하는 데 사용할 수 있는 네 가지 접근 방식입니다.

QThread: 이벤트 루프 옵션이 있는 저수준 API

QThread 는 Qt의 모든 스레드 제어의 기초입니다. 각 QThread 인스턴스는 하나의 스레드를 나타내고 제어합니다.

QThread 인스턴스는 직접 인스턴스화하거나 서브클래싱할 수 있습니다. QThread 인스턴스화는 병렬 이벤트 루프를 제공하여 QObject 슬롯을 보조 스레드에서 호출할 수 있도록 합니다. QThread 을 서브클래싱하면 애플리케이션이 이벤트 루프를 시작하기 전에 새 스레드를 초기화하거나 이벤트 루프 없이 병렬 코드를 실행할 수 있습니다.

QThread 사용 방법에 대한 데모는 QThread class reference스레딩 예제를 참조하세요.

QThreadPool 및 QRunnable: 스레드 재사용하기

스레드를 자주 생성하고 소멸하면 비용이 많이 들 수 있습니다. 이러한 오버헤드를 줄이기 위해 기존 스레드를 새 작업에 재사용할 수 있습니다. QThreadPool 은 재사용 가능한 QThread의 모음입니다.

QThreadPool 의 스레드 중 하나에서 코드를 실행하려면 QRunnable::run()을 다시 구현하고 서브클래싱된 QRunnable 을 인스턴스화합니다. QThreadPool::start ()를 사용하여 QRunnableQThreadPool 의 실행 대기열에 넣습니다. 스레드를 사용할 수 있게 되면 QRunnable::run() 내의 코드가 해당 스레드에서 실행됩니다.

각 Qt 애플리케이션에는 QThreadPool::globalInstance()를 통해 액세스할 수 있는 글로벌 스레드 풀이 있습니다. 이 글로벌 스레드 풀은 CPU의 코어 수에 따라 최적의 스레드 수를 자동으로 유지합니다. 그러나 별도의 QThreadPool 을 생성하여 명시적으로 관리할 수 있습니다.

Qt Concurrent: 상위 수준 API 사용

모듈은 Qt Concurrent 모듈은 맵, 필터, 축소 등 몇 가지 일반적인 병렬 계산 패턴을 처리하는 상위 수준 함수를 제공합니다. QThreadQRunnable 을 사용하는 것과 달리 이러한 함수는 뮤텍스나 세마포어와 같은 저수준 스레딩 프리미티브를 사용할 필요가 없습니다. 대신 QFuture 객체를 반환하여 함수의 결과가 준비되면 결과를 검색하는 데 사용할 수 있습니다. QFuture 은 계산 진행 상황을 쿼리하고 계산을 일시 중지/재개/취소하는 데에도 사용할 수 있습니다. 편의를 위해 QFutureWatcher 는 신호와 슬롯을 통해 QFuture와 상호 작용할 수 있습니다.

Qt Concurrent의 맵, 필터, 축소 알고리즘은 사용 가능한 모든 프로세서 코어에 계산을 자동으로 분배하므로 오늘 작성한 애플리케이션은 나중에 더 많은 코어를 갖춘 시스템에 배포할 때 계속 확장할 수 있습니다.

이 모듈은 다른 스레드에서 모든 함수를 실행할 수 있는 QtConcurrent::run() 함수도 제공합니다. 그러나 QtConcurrent::run()는 매핑, 필터링 및 축소 함수에서 사용할 수 있는 기능의 일부만 지원합니다. QFuture 은 함수의 반환값을 검색하고 스레드가 실행 중인지 확인하는 데 사용할 수 있습니다. 그러나 QtConcurrent::run() 호출은 하나의 스레드만 사용하며 일시 중지/재개/취소할 수 없고 진행 상황을 쿼리할 수 없습니다.

개별 스레드에 대한 자세한 내용은 Qt Concurrent 모듈 설명서를 참조하세요.

WorkerScript: QML의 스레딩

WorkerScript QML 유형을 사용하면 JavaScript 코드를 GUI 스레드와 병렬로 실행할 수 있습니다.

WorkerScript 인스턴스에는 하나의 .js 스크립트가 첨부될 수 있습니다. WorkerScript.sendMessage ()가 호출되면 스크립트는 별도의 스레드(및 별도의 QML context)에서 실행됩니다. 스크립트 실행이 완료되면 WorkerScript.onMessage() 신호 처리기를 호출하는 응답을 GUI 스레드로 다시 보낼 수 있습니다.

WorkerScript 을 사용하는 것은 다른 스레드로 이동한 QObject 워커를 사용하는 것과 유사합니다. 데이터는 시그널을 통해 스레드 간에 전송됩니다.

스크립트를 구현하는 방법과 스레드 간에 전달할 수 있는 데이터 유형 목록에 대한 자세한 내용은 WorkerScript 문서를 참조하세요.

적절한 접근 방식 선택하기

위에서 설명한 것처럼 Qt는 스레드 애플리케이션 개발을 위한 다양한 솔루션을 제공합니다. 주어진 애플리케이션에 적합한 솔루션은 새 스레드의 목적과 스레드의 수명에 따라 달라집니다. 아래는 Qt의 스레딩 기술을 비교한 다음 몇 가지 사용 사례에 대한 권장 솔루션입니다.

솔루션 비교

기능QThreadQRunnableQThreadPoolQtConcurrent::run()Qt Concurrent (매핑, 필터, 축소)WorkerScript
언어C++C++C++C++QML
스레드 우선순위 지정 가능
스레드에서 이벤트 루프 실행 가능
스레드가 신호를 통해 데이터 업데이트를 수신할 수 있음예(작업자가 수신) QObject)예( WorkerScript 에서 수신)
시그널을 사용하여 스레드를 제어할 수 있음예 ( QThread 수신)예 ( QFutureWatcher 에서 수신)
스레드는 다음을 통해 모니터링할 수 있습니다. QFuture부분적으로
일시 중지/재시작/취소 기능 내장

사용 사례 예시

스레드 수명운영솔루션
한 번의 호출다른 스레드 내에서 새로운 선형 함수를 실행하고, 선택적으로 실행 중에 진행 상황을 업데이트합니다.Qt는 다양한 솔루션을 제공합니다:
한 번의 호출다른 스레드 내에서 기존 함수를 실행하고 반환값을 가져옵니다.QtConcurrent::run()를 사용하여 함수를 실행합니다. QFutureWatcher 함수가 반환되면 finished() 신호를 보내고 QFutureWatcher::result()를 호출하여 함수의 반환값을 가져오도록 합니다.
한 번 호출사용 가능한 모든 코어를 사용하여 컨테이너의 모든 항목에 대해 작업을 수행합니다. 예를 들어 이미지 목록에서 썸네일을 생성합니다.Qt ConcurrentQtConcurrent::filter() 함수를 사용하여 컨테이너 요소를 선택하고 QtConcurrent::map() 함수를 사용하여 각 요소에 연산을 적용합니다. 출력을 단일 결과로 통합하려면 QtConcurrent::filteredReduced() 및 QtConcurrent::mappedReduced()를 대신 사용합니다.
한 번 호출/영구순수 QML 애플리케이션에서 긴 계산을 수행하고 결과가 준비되면 GUI를 업데이트합니다.계산 코드를 .js 스크립트에 배치하고 WorkerScript 인스턴스에 첨부합니다. WorkerScript.sendMessage ()를 호출하여 새 스레드에서 계산을 시작합니다. 스크립트에서 sendMessage()도 호출하여 결과를 다시 GUI 스레드로 전달하도록 합니다. onMessage 에서 결과를 처리하고 거기서 GUI를 업데이트합니다.
영구요청에 따라 다른 작업을 수행하거나 작업할 새 데이터를 수신할 수 있는 객체를 다른 스레드에 두세요.QObject 을 서브클래스화하여 워커를 생성합니다. 이 워커 객체와 QThread 를 인스턴스화합니다. 워커를 새 스레드로 이동합니다. 대기 중인 신호 슬롯 연결을 통해 작업자 객체에 명령이나 데이터를 보냅니다.
영구스레드가 신호나 이벤트를 수신할 필요가 없는 다른 스레드에서 비용이 많이 드는 작업을 반복적으로 수행합니다.QThread::run()의 재구현 내에서 직접 무한 루프를 작성합니다. 이벤트 루프 없이 스레드를 시작합니다. 스레드가 신호를 방출하여 데이터를 GUI 스레드로 다시 보내도록 합니다.

© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.