日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長(zhǎng)提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請(qǐng)做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

大多數(shù)線程池實(shí)現(xiàn)都離不開鎖的使用,如互斥量pthread_mutex*結(jié)合條件變量pthread_cond*。眾所周知,鎖的使用對(duì)于程序性能影響較大,雖然現(xiàn)有的pthread_mutex*在鎖的申請(qǐng)與釋放方面做了較大的優(yōu)化,但是,線程池的實(shí)現(xiàn)是可以做到無(wú)鎖化的。

1.常見線程池實(shí)現(xiàn)原理

linux c編程之高效線程池如何實(shí)現(xiàn)無(wú)瑣化

 

如上圖所示,工作隊(duì)列由主線程和工作者線程共享,主線程將任務(wù)放進(jìn)工作隊(duì)列,工作者線程從工作隊(duì)列中取出任務(wù)執(zhí)行。共享工作隊(duì)列的操作需在互斥量的保護(hù)下安全進(jìn)行,主線程將任務(wù)放進(jìn)工作隊(duì)列時(shí)若檢測(cè)到當(dāng)前待執(zhí)行的工作數(shù)目小于工作者線程總數(shù),則需使用條件變量喚醒可能處于等待狀態(tài)的工作者線程。當(dāng)然,還有其他地方可能也會(huì)使用到互斥量和條件變量,不再贅述。

2.無(wú)鎖化線程池實(shí)現(xiàn)原理

linux c編程之高效線程池如何實(shí)現(xiàn)無(wú)瑣化

 

為解決無(wú)鎖化的問(wèn)題,需要避免共享資源的競(jìng)爭(zhēng),因此將共享工作隊(duì)列加以拆分成每工作線程一個(gè)工作隊(duì)列的方式。對(duì)于主線程放入工作和工作線程取出任務(wù)的競(jìng)爭(zhēng)問(wèn)題,可以采取環(huán)形隊(duì)列的方式避免。在解決了鎖機(jī)制之后,就只剩下條件變量的問(wèn)題了,條件變量本身即解決條件滿足時(shí)的線程通信問(wèn)題,而信號(hào)作為一種通信方式,可以代替之,其大體編程范式為:

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服務(wù)器架構(gòu)師學(xué)習(xí)資料私信“資料”(資料包括C/C++,Linux,golang技術(shù),Nginx,ZeroMQ,MySQL,redis,fastdfs,MongoDB,ZK,流媒體,CDN,P2P,K8S,Docker,TCP/IP,協(xié)程,DPDK,ffmpeg等),免費(fèi)分享

linux c編程之高效線程池如何實(shí)現(xiàn)無(wú)瑣化

 

3.無(wú)鎖化線程池具體實(shí)現(xiàn)

在無(wú)鎖線程池中,區(qū)別于常見線程池的地方主要在于信號(hào)與條件變量、任務(wù)調(diào)度算法、增加或減少線程數(shù)目后的任務(wù)遷移,另外還有一點(diǎn)就是環(huán)形隊(duì)列的實(shí)現(xiàn)參考了Linux內(nèi)核中的kfifo實(shí)現(xiàn)。

(1) 信號(hào)與條件變量

信號(hào)與條件變量的區(qū)別主要在于條件變量的喚醒(signal)對(duì)于接收線程而言可以忽略,而在未設(shè)置信號(hào)處理函數(shù)的情況下信號(hào)的接收會(huì)導(dǎo)致接收線程甚至整個(gè)程序的終止,因此需要在線程池產(chǎn)生線程之前指定信號(hào)處理函數(shù),這樣新生的線程會(huì)繼承這個(gè)信號(hào)處理函數(shù)。多線程中信號(hào)的發(fā)送主要采用pthread_kill,為避免使用其他信號(hào),本程序中使用了SIGUSR1。

(2) 任務(wù)調(diào)度算法

常見線程池實(shí)現(xiàn)的任務(wù)調(diào)度主要在操作系統(tǒng)一級(jí)通過(guò)線程調(diào)度實(shí)現(xiàn)。考慮到負(fù)載均衡,主線程放入任務(wù)時(shí)應(yīng)采取合適的任務(wù)調(diào)度算法將任務(wù)放入對(duì)應(yīng)的工作者線程隊(duì)列,本程序目前已實(shí)現(xiàn)Round-Robin和Least-Load算法。Round-Robin即輪詢式地分配工作,Least-Load即選擇當(dāng)前具有最少工作的工作者線程放入。

(3) 任務(wù)遷移

在線程的動(dòng)態(tài)增加和減少的過(guò)程中,同樣基于負(fù)載均衡的考量,涉及到現(xiàn)有任務(wù)的遷移問(wèn)題。負(fù)載均衡算法主要基于平均工作量的思想,即統(tǒng)計(jì)當(dāng)前時(shí)刻的總?cè)蝿?wù)數(shù)目,均分至每一個(gè)線程,求出每個(gè)工作者線程應(yīng)該增加或減少的工作數(shù)目,然后從頭至尾遍歷,需要移出工作的線程與需要移入工作的線程執(zhí)行任務(wù)遷移,相互抵消。最后若還有多出來(lái)的工作,再依次分配。遷入工作不存在競(jìng)態(tài),因?yàn)榧尤牍ぷ魇冀K由主線程完成,而遷出工作則存在競(jìng)態(tài),因?yàn)樵谶w出工作的同時(shí)工作者線程可能在同時(shí)執(zhí)行任務(wù)。所以需要采用原子操作加以修正,其主要思想即預(yù)取技術(shù),大致實(shí)現(xiàn)為:

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在線程的動(dòng)態(tài)減少后,原先線程上未能執(zhí)行完的任務(wù)只需要由
    //主線程再次根據(jù)任務(wù)調(diào)度算法重新分配至其他存活的工作者線程隊(duì)列中即可,不
    //存在上述問(wèn)題,當(dāng)然,此時(shí)可以同時(shí)執(zhí)行負(fù)載均衡算法加以優(yōu)化。
}

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

源碼中環(huán)形隊(duì)列實(shí)現(xiàn)主要參考了linux內(nèi)核中kfifo的實(shí)現(xiàn),如下圖所示:

linux c編程之高效線程池如何實(shí)現(xiàn)無(wú)瑣化

 

隊(duì)列長(zhǎng)度為2的整次冪,out和in下標(biāo)一直遞增至越界后回轉(zhuǎn),其類型為unsigned int,即out指針一直追趕in指針,out和in映射至FiFo的對(duì)應(yīng)下標(biāo)處,其間的元素即為隊(duì)列元素。

分享到:
標(biāo)簽:線程
用戶無(wú)頭像

網(wǎng)友整理

注冊(cè)時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊(cè)賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過(guò)答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫(kù),初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績(jī)?cè)u(píng)定2018-06-03

通用課目體育訓(xùn)練成績(jī)?cè)u(píng)定