日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

线程池 c linux 编程,关于c++:linux-c编程之高效线程池如何实现无琐化

發(fā)布時間:2025/3/21 linux 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 线程池 c linux 编程,关于c++:linux-c编程之高效线程池如何实现无琐化 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

大多數線程池實現都離不開鎖的應用,如互斥量pthread_mutex*聯合條件變量pthread_cond*。家喻戶曉,鎖的應用對于程序性能影響較大,盡管現有的pthread_mutex*在鎖的申請與開釋方面做了較大的優(yōu)化,然而,線程池的實現是能夠做到無鎖化的。

1.常見線程池實現原理

如上圖所示,工作隊列由主線程和工作者線程共享,主線程將工作放進工作隊列,工作者線程從工作隊列中取出工作執(zhí)行。共享工作隊列的操作需在互斥量的愛護下平安進行,主線程將工作放進工作隊列時若檢測到以后待執(zhí)行的工作數目小于工作者線程總數,則需應用條件變量喚醒可能處于期待狀態(tài)的工作者線程。當然,還有其余中央可能也會應用到互斥量和條件變量,不再贅述。

2.無鎖化線程池實現原理

為解決無鎖化的問題,須要防止共享資源的競爭,因而將共享工作隊列加以拆分成每工作線程一個工作隊列的形式。對于主線程放入工作和工作線程取出工作的競爭問題,能夠采取環(huán)形隊列的形式防止。在解決了鎖機制之后,就只剩下條件變量的問題了,條件變量自身即解決條件滿足時的線程通信問題,而信號作為一種通信形式,能夠代替之,其大體編程范式為:

sigemptyset (&oldmask);sigemptyset (&signal_mask);sigaddset (&signal_mask, SIGUSR1);rc = pthread_sigmask(SIG_BLOCK, &signal_mask, NULL);if (rc != 0) { debug(TPOOL_ERROR, "SIG_BLOCK failed"); return -1;}...while (!condition) { rc = sigwait (&signal_mask, NULL); if (rc != 0) { debug(TPOOL_ERROR, "sigwait failed"); return -1; }}rc = pthread_sigmask(SIG_SETMASK, &oldmask, NULL);if (rc != 0) { debug(TPOOL_ERROR, "SIG_SETMASK failed"); return -1;}

須要C/C++ Linux服務器架構師學習材料加qun(563998835)(材料包含C/C++,Linux,golang技術,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒體,CDN,P2P,K8S,Docker,TCP/IP,協程,DPDK,ffmpeg等),收費分享

3.無鎖化線程池具體實現

在無鎖線程池中,區(qū)別于常見線程池的中央次要在于信號與條件變量、任務調度算法、減少或縮小線程數目后的工作遷徙,另外還有一點就是環(huán)形隊列的實現參考了Linux內核中的kfifo實現。

(1) 信號與條件變量

信號與條件變量的區(qū)別次要在于條件變量的喚醒(signal)對于接管線程而言能夠疏忽,而在未設置信號處理函數的狀況下信號的接管會導致接管線程甚至整個程序的終止,因而須要在線程池產生線程之前指定信號處理函數,這樣新生的線程會繼承這個信號處理函數。多線程中信號的發(fā)送次要采納pthread_kill,為防止應用其余信號,本程序中應用了SIGUSR1。

(2) 任務調度算法

常見線程池實現的任務調度次要在操作系統一級通過線程調度實現。思考到負載平衡,主線程放入工作時應采取適合的任務調度算法將工作放入對應的工作者線程隊列,本程序目前已實現Round-Robin和Least-Load算法。Round-Robin即輪詢式地調配工作,Least-Load即抉擇以后具備起碼工作的工作者線程放入。

(3) 工作遷徙

在線程的動靜減少和縮小的過程中,同樣基于負載平衡的考量,波及到現有工作的遷徙問題。負載平衡算法次要基于均勻工作量的思維,即統計以后時刻的總任務數目,均分至每一個線程,求出每個工作者線程應該減少或縮小的工作數目,而后從頭至尾遍歷,須要移出工作的線程與須要移入工作的線程執(zhí)行工作遷徙,互相對消。最初若還有多進去的工作,再順次調配。遷入工作不存在競態(tài),因為退出工作始終由主線程實現,而遷出工作則存在競態(tài),因為在遷出工作的同時工作者線程可能在同時執(zhí)行工作。所以須要采納原子操作加以修改,其次要思維即預取技術,大抵實現為:

do { work = NULL; if (thread_queue_len(thread) <= 0) //also atomic break; tmp = thread->out; //prefetch work work = &thread->work_queue[queue_offset(tmp)];} while (!__sync_bool_compare_and_swap(&thread->out, tmp, tmp + 1));if (work) { // do something在線程的動靜縮小后,原先線程上未能執(zhí)行完的工作只須要由 //主線程再次依據任務調度算法重新分配至其余存活的工作者線程隊列中即可,不 //存在上述問題,當然,此時能夠同時執(zhí)行負載平衡算法加以優(yōu)化。}

(4) 環(huán)形隊列

源碼中環(huán)形隊列實現次要參考了linux內核中kfifo的實現,如下圖所示:

隊列長度為2的整次冪,out和in下標始終遞增至越界后回轉,其類型為unsigned int,即out指針始終追趕in指針,out和in映射至FiFo的對應下標處,其間的元素即為隊列元素。

總結

以上是生活随笔為你收集整理的线程池 c linux 编程,关于c++:linux-c编程之高效线程池如何实现无琐化的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。