QCoro 라이브러리는 Qt와 함께 C++20 코루틴을 사용할 수 있는 도구 세트를 제공합니다.
코루틴이 얼마나 놀라운지 알아보려면 아래 예를 살펴보세요.
QNetworkAccessManager networkAccessManager;// 응답을 co_await - QNetworkReply가 완료될 때까지 코루틴이 일시 중지됩니다.// 코루틴이 일시 중지되는 동안 *Qt 이벤트 루프는 평소대로 실행됩니다*.const QNetworkReply *reply = co_await networkAccessManager.get(url); // 응답이 완료되면 아무 놀라운 일도 일어나지 않은 것처럼 코드가 여기에서 다시 시작됩니다. ;-)const auto data = reply->readAll();
쿠루틴 TS를 지원하는 컴파일러가 필요합니다. 지원되는 컴파일러 및 버전 목록은 설명서를 참조하세요.
선적 서류 비치
QCoro는 Qt와 함께 C++20 코루틴을 쉽게 사용하는 데 필요한 도구를 제공합니다. 라이브러리의 초석은 QCoro::Task<T>
입니다. 이는 실행된 코루틴을 나타내며 호출자가 코루틴 결과를 비동기적으로 기다릴 수 있도록 합니다. 또한 QCoro는 비동기 작업을 직접 co_await
할 수 있는 QTimer
, QNetworkReply
, QDBusPendingCall
, QFuture
등과 같은 일반적인 Qt 유형에 대한 래퍼 세트를 제공합니다.
또한 많은 기본 Qt 함수와 유형을 래핑하여 코루틴 친화적으로 만들 수 있는 마법의 qCoro()
함수가 있습니다.
지원되는 모든 기능과 Qt 유형의 전체 목록은 설명서를 확인하세요.
QDBusPendingCall
QCoro는 비동기 D-Bus 호출이 완료될 때까지 기다릴 수 있습니다. QCoro와 함께 QDBusPendingCallWatcher
사용할 필요가 없습니다. 대신 결과를 co_await
하면 됩니다. co_awaiting 동안 Qt 이벤트 루프는 평소대로 실행됩니다.
QDBusInterface RemoteServiceInterface{serviceName, objectPath, 인터페이스};const QDBusReply<bool> isReady = co_await remoteServiceInterface.asyncCall(QStringLiteral("isReady"));
여기에 전체 문서가 있습니다.
QFuture
QFuture는 비동기 작업의 결과를 나타냅니다. 일반적으로 미래가 준비되면 알림을 받으려면 QFutureWatcher
사용해야 합니다. QCoro를 사용하면 co_await
할 수 있습니다!
const QFuture<int> task1 = QtConcurrent::run(....);const QFuture<int> task2 = QtConcurrent::run(....);const int a = co_await task1;const int b = co_await task2; co_return a + b;
여기에 전체 문서가 있습니다.
QNetworkReply
Qt를 사용하여 네트워크 요청을 수행하는 것은 지루할 수 있습니다. 신호/슬롯 접근 방식은 코드 흐름을 중단시킵니다. 요청 연결 및 오류 처리가 빠르게 엉망이 되고 코드가 수많은 기능으로 분할됩니다. 그러나 QCoro에서는 그렇지 않습니다. QNetworkReply
가 완료될 때까지 간단히 co_await
할 수 있습니다.
QNetworkAccessManager qnam; QNetworkReply *reply = qnam.get(QStringLiteral("https://github.com/qcoro/qcoro"));const autocontent = co_await reply; reply->deleteLater();if (reply->error() != QNetworkReply::NoError) {co_return handlerError(reply); }const 자동 링크 = findLinkInReturnedHtmlCode(contents); reply = qnam.get(link);const 자동 데이터 = co_await reply; reply->deleteLater();if (reply->error() != QNetworkReply::NoError) {co_return handlerError(reply); } ...
여기에 전체 문서가 있습니다.
QTimer
어쩌면 코드 실행을 잠시 지연하고 싶을 수도 있고, 일부 코드를 반복적인 간격으로 실행하고 싶을 수도 있습니다. 이는 co_await
사용하면 매우 간단해집니다.
Q타이머 타이머; 타이머.setInterval(1s); timer.start();for (int i = 1; i <= 100; ++i) {co_await 타이머;qDebug() << "" << i << "초를 기다리는 중..."; }qDebug() << "완료!";
여기에 전체 문서가 있습니다.
QIODevice
QIODevice
는 데이터를 비동기적으로 쓰고 읽을 수 있도록 하는 Qt의 많은 클래스에 대한 기본 클래스입니다. 읽을 준비가 된 데이터가 있는지 어떻게 알 수 있나요? QIODevice::readyRead()
singal에 연결하거나 QCoro를 사용하고 객체를 co_await
할 수 있습니다.
소켓->write("PING");// "pong"을 기다리는 중 const auto data = co_await 소켓;co_returncalculateLatency(data);
여기에 전체 문서가 있습니다.
자세한 내용은 전체 문서를 확인하세요.
코루틴의 결과를 처리하기 위해 co_await
사용하는 것이 불가능한 경우가 있습니다. 일반적으로 코루틴을 지원하지 않는 타사 코드와 인터페이스할 때입니다. 이러한 시나리오에서는 코루틴이 완료될 때 비동기적으로 호출되는 연속 콜백을 코루틴에 연결하는 것이 가능합니다.
void RegularFunction() {someCoroutineReturningInt().then([](int result) {// 결과 처리}); }
연속 콜백은 코루틴일 수도 있으며 전체 표현식의 결과는 Task입니다. 여기서 T는 연속의 반환 유형입니다. 덕분에 전체 체인을 co_await
하거나 여러 .then()
연속을 연결하는 것이 가능합니다.
여기에 전체 문서가 있습니다.
Generator는 여러 값을 느리게 생성하는 코루틴입니다. Qt와 관련된 것은 없지만 QCoro는 사용자가 Qt 애플리케이션에서 사용자 정의 생성기를 만드는 데 필요한 도구를 제공합니다.
QCoro는 동기 생성기( QCoro::Generator<T>
)와 비동기 생성기( QCoro::AsyncGenerator<T>
) 모두에 대한 API를 제공합니다. 두 생성기 모두 컨테이너와 같은 API를 제공합니다. 즉, 잘 알려지고 확립된 API이며 생성기를 기존 알고리즘과 호환되게 만드는 반복기와 같은 개체를 반환하는 begin()
및 end()
멤버 함수입니다.
QCoro::Generator<int> fibonacci() { quint64 a = 0, b = 0; Q_FOREVER {co_yield b;const auto tmp = b; a = b; b += tmp; } }void printFib(quint64 max) {for (auto fib : fibonacci()) {if (fib > max) {break; } std::cout << fib << std::endl; } }
여기에 전체 문서가 있습니다.
MIT License
Copyright (c) 2022 Daniel Vrátil <[email protected]>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.