最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Qt使用QtConcurrent::run實(shí)現(xiàn)異步等待和同步調(diào)用

 更新時(shí)間:2025年09月18日 10:48:49   作者:__ocean  
Qt使用QtConcurrent::run實(shí)現(xiàn)C#中類似async await的用法,雖不如C#的async/await靈活,但可滿足業(yè)務(wù)需求并提升代碼可讀性,下面就來詳細(xì)的介紹一下QtConcurrent::run實(shí)現(xiàn)異步等待和同步調(diào)用

在使用Qt進(jìn)行開發(fā)時(shí),經(jīng)常需要使用異步方法,不同于C#的async/await,Qt中提供了QtConcurrent::run接口方法可供調(diào)用,習(xí)慣了C#的await,便想著能不能封裝幾個(gè)類似的函數(shù)在項(xiàng)目中使用,探索了下,有如下幾個(gè)方案

首先定義全局線程池

	inline QThreadPool* globalThreadPool() 
	{
		static QThreadPool* pool = []() {
			QThreadPool* p = new QThreadPool;
			p->setMaxThreadCount(QThread::idealThreadCount());
			return p;
			}();
		return pool;
	}

方案一,最簡(jiǎn)單的封裝調(diào)用,直接異步調(diào)用,無任何返回結(jié)果,也不會(huì)卡住調(diào)用線程:

	auto CallAsync = [](auto func){
		QtConcurrent::run(globalThreadPool(), func);
	};

調(diào)用時(shí)用法如下:

CallAsync([](){
	// do something in theadpool...
});

方案二,如果我們想在異步執(zhí)行時(shí),調(diào)用線程同步等待,可封裝如下:

auto AwaitCallAsync = [](auto func, int timeoutSeconds = 5) -> bool
{        
    QFuture<void> future = QtConcurrent::run(globalThreadPool(), func);
    
    // 使用智能指針管理對(duì)象生命周期
    auto watcher = std::make_shared<QFutureWatcher<void>>();
    auto loop = std::make_shared<QEventLoop>();
    auto timer = std::make_shared<QTimer>();
    
    bool timedOut = false;    
    if (timeoutSeconds > 0) {
        timer->setInterval(timeoutSeconds * 1000);
        timer->setSingleShot(true);
        QObject::connect(timer.get(), &QTimer::timeout, [&timedOut, loop]() {
            timedOut = true;
            loop->quit();
        });
        timer->start();
    }    
    QObject::connect(watcher.get(), &QFutureWatcher<void>::finished, loop.get(), &QEventLoop::quit);
    watcher->setFuture(future);    
    loop->exec();
    
    // 清理資源
    if (!timedOut && timeoutSeconds > 0) {
        timer->stop();
    }    
    return !timedOut; // 返回是否正常完成
};

此時(shí),執(zhí)行AwaitCallAsync時(shí),調(diào)用線程會(huì)同步等待但并不會(huì)卡住線程,為了避免長(zhǎng)時(shí)間等待,也可以添加超時(shí)參數(shù)。

方案三,有時(shí),我們?cè)谙M诋惒胶瘮?shù)調(diào)用完成后能回到調(diào)用線程繼續(xù)執(zhí)行,那么可以添加QFutureWatcher,監(jiān)控異步函數(shù)的執(zhí)行,然后在QFutureWatcher發(fā)送finished時(shí)執(zhí)行另一個(gè)函數(shù),如下:

auto CallAsyncWithCallback = [](auto func_async, auto func_callback){
		auto future = QtConcurrent::run(globalThreadPool(), func_async);
		auto watcher = new QFutureWatcher<void>();
		// 連接信號(hào),此處connect會(huì)被自動(dòng)執(zhí)行為Qt::QueuedConnection
		QObject::connect(watcher, &QFutureWatcher<void>::finished, [func_callback, watcher]() mutable { 
				func_callback();
				watcher->deleteLater(); // 完成后自動(dòng)清理
			});
		watcher->setFuture(future);
	}

上面的connect是在調(diào)用線程中執(zhí)行的,而finished信號(hào)是在線程池中子線程中發(fā)出來的,跨線程所以Qt會(huì)選擇用Qt::QueuedConnection的方式執(zhí)行Lambda 表達(dá)式。

方案四,有時(shí),我們希望回調(diào)函數(shù)在特定線程比如主線程中執(zhí)行,如下:

auto CallAsyncWithUICallback = [](FuncAsync func_async, FuncCallback func_callback_onUI) {
		QtConcurrent::run([func_async, func_callback]() {			
			func_async(); // 在子線程執(zhí)行異步函數(shù)
			
			// 回到主線程執(zhí)行回調(diào)
			QMetaObject::invokeMethod(qApp, [func_callback]() {
				func_callback();
				}, Qt::QueuedConnection);
			});
	}

注意,在調(diào)用invokeMethod時(shí),要顯示指定Qt::QueuedConnection。

總體來說,C#的async await很靈活很強(qiáng)大,Qt雖然不能與之相比,但經(jīng)過簡(jiǎn)單的封裝,也能寫出比較靈活或者符合自己業(yè)務(wù)需求而又簡(jiǎn)潔好讀的異步代碼。

到此這篇關(guān)于Qt使用QtConcurrent::run實(shí)現(xiàn)異步等待和同步調(diào)用的文章就介紹到這了,更多相關(guān)Qt QtConcurrent::run異步等待和同步調(diào)用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:

相關(guān)文章

  • sigsetjmp的用法總結(jié)

    sigsetjmp的用法總結(jié)

    sigsetjmp()會(huì)保存目前堆棧環(huán)境,然后將目前的地址作一個(gè)記號(hào),而在程序其他地方調(diào)用siglongjmp()時(shí)便會(huì)直接跳到這個(gè)記號(hào)位置,然后還原堆棧,繼續(xù)程序的執(zhí)行
    2013-09-09
  • 深入C++中API的問題詳解

    深入C++中API的問題詳解

    本篇文章是對(duì)C++中API的問題進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • C++中靜態(tài)存儲(chǔ)區(qū)與棧以及堆的區(qū)別詳解

    C++中靜態(tài)存儲(chǔ)區(qū)與棧以及堆的區(qū)別詳解

    本篇文章是對(duì)C++中靜態(tài)存儲(chǔ)區(qū)與棧以及堆的區(qū)別進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • C++ 匈牙利算法案例分析詳解

    C++ 匈牙利算法案例分析詳解

    這篇文章主要介紹了C++ 匈牙利算法案例分析詳解,本篇文章通過簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • Matlab中圖像數(shù)字水印算法的原理與實(shí)現(xiàn)詳解

    Matlab中圖像數(shù)字水印算法的原理與實(shí)現(xiàn)詳解

    數(shù)字水印技術(shù)作為信息隱藏技術(shù)的一個(gè)重要分支,是將信息(水印)隱藏于數(shù)字圖像、視頻、音頻及文本文檔等數(shù)字媒體中,從而實(shí)現(xiàn)隱秘傳輸、存儲(chǔ)、標(biāo)注、身份識(shí)別、版權(quán)保護(hù)和防篡改等目的。本文就來講講圖像數(shù)字水印算法的原理與實(shí)現(xiàn),感興趣的可以了解一下
    2023-04-04
  • 解析如何利用switch語句進(jìn)行字符統(tǒng)計(jì)

    解析如何利用switch語句進(jìn)行字符統(tǒng)計(jì)

    本篇文章是對(duì)如何利用switch語句進(jìn)行字符統(tǒng)計(jì)的方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-06-06
  • C語言實(shí)現(xiàn)點(diǎn)菜系統(tǒng)

    C語言實(shí)現(xiàn)點(diǎn)菜系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)點(diǎn)菜系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • C語言簡(jiǎn)明講解變量的屬性

    C語言簡(jiǎn)明講解變量的屬性

    我們知道以在?C?語言中的變量有自己的屬性,只要在定義變量的時(shí)候加上“屬性”關(guān)鍵字即可?!皩傩浴标P(guān)鍵字指明變量的特有意義,但是?register?關(guān)鍵字只是請(qǐng)求寄存器變量,所以不一定會(huì)成功
    2022-04-04
  • QT中對(duì)Mat類的一些操作詳解

    QT中對(duì)Mat類的一些操作詳解

    本文主要介紹了QT中對(duì)Mat類的一些操作詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-06-06
  • C語言編寫基于TCP和UDP協(xié)議的Socket通信程序示例

    C語言編寫基于TCP和UDP協(xié)議的Socket通信程序示例

    這篇文章主要介紹了C語言編寫基于TCP和UDP協(xié)議的Socket通信程序示例,其中TCP的客戶端與服務(wù)器端采用多線程實(shí)現(xiàn),需要的朋友可以參考下
    2016-03-03

最新評(píng)論

金华市| 伊金霍洛旗| 敖汉旗| 天全县| 兰坪| 清原| 治多县| 陆良县| 伊通| 阜康市| 北川| 秦安县| 上林县| 西平县| 漳平市| 邯郸市| 罗江县| 大石桥市| 乌拉特后旗| 平武县| 万载县| 安图县| 建水县| 大悟县| 同德县| 抚州市| 喀喇| 闽侯县| 马尔康县| 饶河县| 隆昌县| 沁水县| 修武县| 平塘县| 互助| 温州市| 莒南县| 遵义县| 深水埗区| 海阳市| 社旗县|