728x90
반응형
- QCoro 는
C++20
의 코루틴(coroutine
) 기능을Qt
프레임워크 에 자연스럽게 통합하여, 비동기 코드를 훨씬 간결하고 직관적으로 작성할 수 있도록 도와주는 라이브러리입니다.
- 🔗 GitHub: https://github.com/qcoro/qcoro
- 컴파일러
C++20
이상- GCC: 10 이상
- Clang: 13 이상
- MSVC: 2019 version 16.10 이상
Qt 6.x
(일부Qt 5.x
도 지원)Linux
,macOS
,Windows
호환
- 전통적으로
Qt
에서는 비동기 작업을QFuture
,QPromise
,signal-slot
, 또는callback
메커니즘을 사용해 처리해왔습니다. - 하지만 이런 방식은 코드 가독성이 떨어지고, 복잡한 로직에서는 콜백 지옥(
callback hell
)으로 이어지기 쉽습니다. - QCoro 는 이러한 문제를 해결하기 위해
Qt
의 비동기API
를 코루틴 스타일로 변환하여co_await
를 통해 간결하고 직관적인 비동기 흐름을 구현할 수 있게 해줍니다.
-
Qt 네이티브 지원
QIODevice
,QProcess
,QNetworkReply
,QTimer
등 주요 Qt 클래스에 대한 비동기co_await
지원을 제공합니다.
-
시그널 대기
co_await
를 통해 특정 시그널이 발생할 때까지 대기하는 기능을 제공합니다.
-
커스텀 타입 확장
- 자신만의 타입에 대해서도 코루틴
awaitable
기능을 확장할 수 있습니다.
- 자신만의 타입에 대해서도 코루틴
-
간결한 문법
- 복잡한 상태 관리나 연결 코드를 작성하지 않고, 마치 동기 코드처럼 자연스럽게 작성할 수 있습니다.
-
기본 구조
QCoro::Task<> userDefinedTask(...) { // QCoro 태스크 생성 ... co_await doJob(); // QCoro 대기 (doJob이 종료될 때까지 대기) ... co_return; // QCoro 태스크 리턴 }
-
cpp
#include <QCoreApplication> #include <QNetworkAccessManager> #include <QNetworkRequest> #include <QNetworkReply> #include <QUrl> #include <QDebug> #include <qcoro/qcoro.h> #include <qcoro/network.h> #include <coroutine> QCoro::Task<> fetchData(QNetworkAccessManager &manager) { QUrl url{"https://postman-echo.com/get?foo1=bar1&foo2=bar2"}; QNetworkRequest request(url); auto reply = co_await manager.get(request); // GET URL 결과 대기 QByteArray data = reply->readAll(); qDebug() << "응답 내용:" << data; co_return; // QCoro 태스크 리턴 } int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); QNetworkAccessManager manager; fetchData(manager); // QCoro 태스크 시작 return app.exec(); }
- 분석
co_await manager.get()
호출로 네트워크 응답 완료 시점까지 suspension.- 기존의
connect
와QNetworkReply
처리를 간결화. - 이벤트 루프가 동작 중인 상태에서 코루틴 실행 가능.
-
cpp
#include <QCoreApplication> #include <QProcess> #include <QDebug> #include <qcoro/qcoro.h> #include <qcoro/process.h> #include <coroutine> QCoro::Task<> runProcess() { QProcess process; process.start("echo", {"Hello from QProcess!"}); // 외부 프로그램 echo 실행 const auto result = co_await process; // process 대기 qDebug() << "프로세스 종료 코드:" << result.exitCode; qDebug() << "표준 출력:" << process.readAllStandardOutput(); co_return; // QCoro 태스크 리턴 } int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); runProcess(); // QCoro 태스트 시작 return app.exec(); }
- 분석
process
종료 대기를co_await
로 처리.- 종료 코드와 표준 출력 내용을 바로 가져옴.
-
cpp
#include <QCoreApplication> #include <QTimer> #include <QDebug> #include <qcoro/qcoro.h> #include <qcoro/timer.h> #include <coroutine> QCoro::Task<> waitWithTimer() { QTimer timer; timer.setInterval(2000); // 2000 밀리초 = 2초 timer.setSingleShot(true); // 한번만 실행 co_await timer; // timer 대기 qDebug() << "2초가 경과했습니다."; co_return; // QCoro 태스크 리턴 } int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); waitWithTimer(); // QCoro 태스트 시작 return app.exec(); }
- 분석
- 타이머 만료를
co_await
로 기다림. - 기존
connect
없이 자연스럽게 코루틴 흐름으로 전환.
- 타이머 만료를
-
cpp
#include <QCoreApplication> #include <QFile> #include <QDebug> #include <qcoro/qcoro.h> #include <qcoro/file.h> #include <coroutine> QCoro::Task<> writeAndReadFile() { QFile file("example.txt"); if (co_await file.open(QIODevice::WriteOnly)) { // 파일 열기 대기 co_await file.write("QCoro 파일 비동기 쓰기 테스트"); // 파일 쓰기 대기 file.close(); } if (co_await file.open(QIODevice::ReadOnly)) { // 파일 열기 대기 const QByteArray content = co_await file.readAll(); // 파일 읽기 대기 qDebug() << "읽은 파일 내용:" << content; file.close(); } co_return; // QCoro 태스크 리턴 } int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); writeAndReadFile(); // QCoro 태스크 시작 return app.exec(); }
- 분석
- 파일 열기, 쓰기, 읽기를 모두
co_await
로 간결화. - 코루틴 내에서 직관적인 비동기 입출력 구현 가능.
- 파일 열기, 쓰기, 읽기를 모두
-
cpp
#include <QCoreApplication> #include <QTcpSocket> #include <QDebug> #include <qcoro/qcoro.h> #include <qcoro/socket.h> #include <coroutine> QCoro::Task<> connectToServer() { QTcpSocket socket; co_await socket.connectToHost("example.com", 80); // 연결 대기 if (socket.state() == QAbstractSocket::ConnectedState) { qDebug() << "서버에 연결되었습니다."; socket.write("GET / HTTP/1.1\r\nHost: example.com\r\n\r\n"); while (co_await socket.waitForReadyRead()) { // 읽기 준비 대기 QByteArray response = socket.readAll(); qDebug() << "응답 데이터:" << response; } } else { qDebug() << "서버 연결 실패"; } co_return; // QCoro 태스크 리턴 } int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); connectToServer(); // QCoro 태스크 시작 return app.exec(); }
- 분석
- 비동기 연결과 데이터 수신 대기를 모두
co_await
로 처리. - 콜백 및 이벤트 신호 연결 필요 없이 비동기
TCP
작업 가능.
- 비동기 연결과 데이터 수신 대기를 모두
-
cpp
#include <QApplication> #include <QDialog> #include <QPushButton> #include <QVBoxLayout> #include <QDebug> #include <qcoro/qcoro.h> #include <qcoro/dialog.h> #include <coroutine> QCoro::Task<> showDialog() { QDialog dialog; dialog.setWindowTitle("비동기 QDialog 테스트"); auto layout = new QVBoxLayout(&dialog); auto button = new QPushButton("닫기"); layout->addWidget(button); QObject::connect(button, &QPushButton::clicked, &dialog, &QDialog::accept); int result = co_await dialog; // dialog 대기 (modal 다이얼로그와 비슷한 효과) qDebug() << "다이얼로그 종료, 반환 코드:" << result; co_return; // QCoro 태스크 리턴 } int main(int argc, char *argv[]) { QApplication app(argc, argv); showDialog(); // QCoro 태스크 시작 return app.exec(); }
- 분석
- 다이얼로그가 닫힐 때까지 비동기 대기.
- 기존
exec()
대신co_await
를 사용하여 UI 흐름 제어 가능.
-
cpp
#include <QCoreApplication> #include <QTimer> #include <QEventLoop> #include <QDebug> #include <qcoro/qcoro.h> #include <qcoro/eventloop.h> #include <coroutine> QCoro::Task<> eventLoopExample() { qDebug() << "3초 후에 메시지를 출력합니다."; QEventLoop loop; QTimer::singleShot(3000, &loop, &QEventLoop::quit); // 3000 밀리초 후 종료(quit) 이벤트 생성 co_await loop; // loop 대기 qDebug() << "3초 경과!"; co_return; // QCoro 태스크 리턴 } int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); eventLoopExample(); // QCoro 태스크 시작 return app.exec(); }
- 분석
- 특정 이벤트 발생 전까지 QEventLoop 안에서 대기.
- 기존 이벤트 루프 흐름을 자연스럽게
co_await
로 처리.
-
cpp
#include <QCoreApplication> #include <QtConcurrent> #include <QDebug> #include <qcoro/qcoro.h> #include <qcoro/future.h> #include <coroutine> QCoro::Task<> runConcurrentTask() { auto future = QtConcurrent::run([]() -> int { QThread::sleep(2); return 42; }); int result = co_await future; // future 대기 qDebug() << "QtConcurrent 결과:" << result; co_return; // QCoro 태스크 리턴 } int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); runConcurrentTask(); // QCoro 태스크 시작 return app.exec(); }
- 분석
QtConcurrent
작업의 결과를 자연스럽게 코루틴으로 대기.- 별도 스레드 작업의 결과를 간단히 받아오는 구조.
QCoro
는Qt
의 다양한 비동기 작업을C++20
코루틴으로 감쌀 수 있게 하여, 코드의 가독성과 유지보수성을 크게 높여줍니다.- 복잡한 콜백이나 신호-슬롯 연결 없이도
co_await
로 자연스럽게 이벤트 흐름을 제어할 수 있다는 점이 큰 장점입니다. Qt
를 사용하며 비동기 처리를 자주 다루는 경우,QCoro
는 필수적인 도구가 될 수 있습니다.
- 도움이 되셨으면 하단의 ❤️ 공감 버튼 부탁 드립니다. 감사합니다! 😄
728x90
반응형
'Qt' 카테고리의 다른 글
AI로 Qt 개발을 더 스마트하게 – QodeAssist 소개 및 설치 가이드 (0) | 2025.03.29 |
---|---|
Qt의 High-DPI 지원 (0) | 2025.02.17 |
qt.conf 파일: Qt 애플리케이션의 경로 설정 및 배포 문제 해결 (0) | 2025.02.17 |
KDDockWidgets : Qt 도크 위젯 라이브러리 (dock widget library) (0) | 2025.02.11 |
QxOrm 라이브러리 : C++ Qt ORM(Object Relational Mapping) 및 ODM(Object Document Mapper) 라이브러리 (0) | 2025.02.07 |