www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁(yè) > 公眾號(hào)精選 > CPP開(kāi)發(fā)者
[導(dǎo)讀]眾所周知,STL容器不是線程安全的。對(duì)于vector,即使寫(xiě)方(生產(chǎn)者)是單線程寫(xiě)入,但是并發(fā)讀的時(shí)候,由于潛在的內(nèi)存重新申請(qǐng)和對(duì)象復(fù)制問(wèn)題,會(huì)導(dǎo)致讀方(消費(fèi)者)的迭代器失效。實(shí)際表現(xiàn)也就是招致了coredump。另外一種情況,如果是多個(gè)寫(xiě)方,并發(fā)的push_back(),也會(huì)導(dǎo)...

眾所周知,STL容器不是線程安全的。對(duì)于vector,即使寫(xiě)方(生產(chǎn)者)是單線程寫(xiě)入,但是并發(fā)讀的時(shí)候,由于潛在的內(nèi)存重新申請(qǐng)和對(duì)象復(fù)制問(wèn)題,會(huì)導(dǎo)致讀方(消費(fèi)者)的迭代器失效。實(shí)際表現(xiàn)也就是招致了core dump。另外一種情況,如果是多個(gè)寫(xiě)方,并發(fā)的push_back(),也會(huì)導(dǎo)致core dump。

解法一

加鎖是一種解決方案,比如互斥鎖std::mutex。但是加std::mutex確實(shí)性能較差。對(duì)于多讀少寫(xiě)的場(chǎng)景可以用讀寫(xiě)鎖(也叫共享獨(dú)占鎖)來(lái)緩解。比如C 17引入了std::shared_mutex 。更多鎖的種類可以閱讀之前寫(xiě)的這篇文章:

如何理解互斥鎖、條件變量、讀寫(xiě)鎖以及自旋鎖?

當(dāng)然本文的目的自然不是自我重復(fù)再次介紹一次鎖的使用,請(qǐng)繼續(xù)閱讀解法二!

解法二

更多的時(shí)候,其實(shí)可以通過(guò)固定vector的大小,避免動(dòng)態(tài)擴(kuò)容(無(wú)push_back)來(lái)做到lock-free!

即在開(kāi)始并發(fā)讀寫(xiě)之前(比如初始化)的時(shí)候,給vector設(shè)置好大小。

struct?Data?{
...
};
vector?v;
v.resize(1000);
注意是resize(),不是reserve()

可能大家平時(shí)用reserve()比較多,顧名思義,reserve就是預(yù)留內(nèi)存。為的是避免內(nèi)存重新申請(qǐng)以及容器內(nèi)對(duì)象的拷貝。說(shuō)白了,reserve()是給push_back()準(zhǔn)備的!

而resize除了預(yù)留內(nèi)存以外,還會(huì)調(diào)用容器元素的構(gòu)造函數(shù),不僅分配了N個(gè)對(duì)象的內(nèi)存,還會(huì)構(gòu)造N個(gè)對(duì)象。從這個(gè)層面上來(lái)說(shuō),resize()在時(shí)間效率上是比reserve()低的。但是在多線程的場(chǎng)景下,用resize再合適不過(guò)。

你可以resize好N個(gè)對(duì)象,多線程不管是讀還是寫(xiě),都是通過(guò)容器的下標(biāo)訪問(wèn)operator[]來(lái)訪問(wèn)元素,不要push_back()新元素。所謂的『寫(xiě)操作』在這里不是插入新元素,而是修改舊元素。

如果N的最大個(gè)數(shù)是可以預(yù)期的就直接設(shè)置就好,如果沒(méi)辦法預(yù)期就再把vector搞成ring buffer(環(huán)形隊(duì)列)來(lái)緩解壓力。

可以給元素類加上成員變量標(biāo)記當(dāng)前的讀寫(xiě)狀態(tài)、是否被消費(fèi)等等。

當(dāng)然,你會(huì)說(shuō),如果B,C,D,E,F(xiàn)這個(gè)5個(gè)線程是等價(jià)的,要不停消費(fèi)vector中的元素,會(huì)造成重復(fù)消費(fèi)不?

當(dāng)然會(huì)。你可以把隊(duì)列頭的下標(biāo)定義成原子變量(std::atomic),盡管原子變量也需要做線程同步,但是比一般的鎖開(kāi)銷要小很多啦。

如果你想連原子變量也不用,有沒(méi)有辦法呢?有啊。那就給B,C,D,E,F(xiàn)分配不同的消費(fèi)隊(duì)列啊。比如當(dāng)前有5個(gè)讀線程,那么每個(gè)線程就消費(fèi)下標(biāo)對(duì)5取模之后的某個(gè)固定結(jié)果的下標(biāo)。比如:

  • B消費(fèi):0、5、10、15、……
  • C消費(fèi):1、6、11、16、……
  • D消費(fèi):2、7、12、17、……
  • E消費(fèi):3、8、13、18、……
  • F消費(fèi):4、9、14、19、……
每個(gè)讀線程各自維護(hù)自己當(dāng)前消費(fèi)的最新下標(biāo)。

這樣做有啥問(wèn)題沒(méi)?也有,就是可能會(huì)導(dǎo)致不同的線程繁忙和等待的情況差異巨大:忙的忙死,閑的閑死。具體場(chǎng)景具體分析,總之,無(wú)論如何要控制住。不要讓一個(gè)任務(wù)hang住整個(gè)線程。

vector是順序容器,STL中還有一類關(guān)聯(lián)容器其線程安全問(wèn)題也不容小覷。比如map、unordered_map。

我們可能會(huì)有這樣一種場(chǎng)景:在并發(fā)環(huán)境下,收集一些Key-Value,存儲(chǔ)在某一個(gè)公共的容器中。這里也談一下不用鎖的方案,當(dāng)然做不到放之四海皆準(zhǔn)。它有一些限制條件,只能看是否滿足你的需要了。

當(dāng)有多個(gè)寫(xiě)線程對(duì)情況下,并發(fā)地插入 map/unordered_map都會(huì)引發(fā)core dump。對(duì)此,在某些場(chǎng)景下也可以避免加鎖:如果全量的key有辦法在并發(fā)之前就能拿到的,那么就對(duì)這個(gè)map,提前做一下insert。

并發(fā)環(huán)境中如果只是修改value,而不是插入新key就不會(huì)core dump!不過(guò)如果你沒(méi)辦法保證多個(gè)寫(xiě)線程不會(huì)同時(shí)修改同一個(gè)key的value,那么可能存在value的覆蓋。

無(wú)法保證這點(diǎn)時(shí),還是需要加鎖。不過(guò)可以對(duì)key采取某種hash策略轉(zhuǎn)成整型,然后進(jìn)行分段加鎖,減少一點(diǎn)鎖沖突的概率,或者用一下CAS的策略。

另外對(duì)于unordered_map,在單寫(xiě)多讀的多線程場(chǎng)景下,會(huì)不會(huì)有問(wèn)題呢?也可能有。gcc 4.7.2的unordered_map實(shí)現(xiàn)曾被爆出有這個(gè)問(wèn)題。原因的新插入的元素,觸發(fā)了rehash,讓其他線程在unordered_map中查找的過(guò)程之中,出現(xiàn)了core dump。見(jiàn):

https://stackoverflow.com/questions/16353334/segv-in-gccs-stdunordered-map

我不確定clang以及后續(xù)的gcc版本是否還有此問(wèn)題。應(yīng)該在不添加任何額外同步代碼的情況下,無(wú)法解決。

容器并發(fā)前初始化與偽共享的爭(zhēng)議

本文內(nèi)容曾經(jīng)在知乎上寫(xiě)過(guò),有網(wǎng)友評(píng)論:解法二會(huì)有false sharing(偽共享)的問(wèn)題。

這里簡(jiǎn)單回應(yīng)一下,談?wù)搨喂蚕?,要考慮具體的場(chǎng)景。的確某些時(shí)候偽共享會(huì)帶來(lái)性能損失,但是要和并行化帶來(lái)的性能提升來(lái)比較,孰高孰低。如果并行提升的性能足夠多,是足以彌補(bǔ)這點(diǎn)偽共享的損失的。

比如我要進(jìn)行遠(yuǎn)程IO,我有N個(gè)key要查詢r(jià)edis,把他們的結(jié)果存儲(chǔ)到一個(gè)vector中,這個(gè)vector的寫(xiě)入操作在IO的異步回調(diào)函數(shù)中。在不加任何額外處理的情況下,極大概率會(huì)導(dǎo)致vector的core dump。

而如果vector初始化一下,則無(wú)需在回調(diào)函數(shù)中加鎖,就能保證安全。這時(shí)候并行IO本身帶來(lái)的性能提升,遠(yuǎn)遠(yuǎn)大于可能的偽共享帶來(lái)?yè)p失。

這里為什么說(shuō)可能呢?因?yàn)閭喂蚕淼挠|發(fā)沒(méi)你想象的這么簡(jiǎn)單。如何成功模擬出一次偽共享帶來(lái)性能損失的例子?你可以寫(xiě)程序自測(cè)一下,并不容易……甚至你改一下優(yōu)化級(jí)別,改成O2,測(cè)試表現(xiàn)都很不一樣。

一般網(wǎng)絡(luò)上談?wù)搨喂蚕頃r(shí)所舉的例子,并不是一個(gè)vector中多個(gè)元素之間并行讀寫(xiě)觸發(fā)了偽共享。而是vector的元素類型是一個(gè)對(duì)象,對(duì)象中有2個(gè)數(shù)據(jù)字段a和b,在多線程分別更新同一個(gè)元素的a和b字段的時(shí)候,導(dǎo)致了偽共享。

比如一個(gè)線程更新vector中每個(gè)元素的a字段,另外一個(gè)線程更新vector中每個(gè)元素的b字段。

Anyway,偽共享的議題比較復(fù)雜,歡迎留意評(píng)論!


- EOF -

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

雀巢公司(Nestle)表示,已經(jīng)同意從星巴克(Starbucks Corp)手中收購(gòu)Seattle's Best Coffee品牌,以加強(qiáng)該公司在美國(guó)的咖啡業(yè)務(wù)。雀巢公司是雀巢咖啡(Nescafe)和Nespresso...

關(guān)鍵字: TTL ST SE AFE

騰盛博藥生物科技有限公司公布了兩項(xiàng)在美國(guó)健康志愿者中開(kāi)展的評(píng)估長(zhǎng)效BRII-732和BRII-778的1期研究最新數(shù)據(jù),這兩種在研候選藥物旨在用于治療人類免疫缺陷病毒(HIV)感染。兩項(xiàng)研究結(jié)果均表明,BRII-732和...

關(guān)鍵字: FIR ST RS

標(biāo)普500指數(shù)今年迄今為止下跌22.7%,但高盛(Goldman Sachs)策略師認(rèn)為估值依然太高。摩根士丹利旗下的Morgan Stanley Wealth Management稱,面對(duì)高通脹環(huán)境下的利率大幅上升,股...

關(guān)鍵字: DMA MANAGEMENT 高通 ST

奈飛(Netflix)今年早些時(shí)候從數(shù)據(jù)中看到了一個(gè)令人擔(dān)憂的信號(hào):用戶訪問(wèn)該流媒體服務(wù)的頻率下降了。該公司對(duì)其用戶在四周時(shí)間里觀看其內(nèi)容的天數(shù)進(jìn)行了跟蹤,并擔(dān)心訪問(wèn)頻率的下降會(huì)增加用戶取消訂閱的可能性。在發(fā)現(xiàn)這一問(wèn)題之...

關(guān)鍵字: 信號(hào) 流媒體 TI ST

鄭州2022年10月17日 /美通社/ -- 近日,《福布斯》發(fā)布了"2022年全球最佳雇主榜單"(The World's Best Employers 2022),中國(guó)平安再度上榜并排名全...

關(guān)鍵字: 福布斯 ST TI BSP

蘇州2022年10月17日 /美通社/ -- 開(kāi)拓藥業(yè)(股票代碼:9939.HK),一家專注于潛在同類首創(chuàng)和同類最佳創(chuàng)新藥物研發(fā)及產(chǎn)業(yè)化的生物制藥公司,宣布其自主研發(fā)、潛在同類首創(chuàng)的福瑞他恩(KX-826)治療痤瘡的中國(guó)...

關(guān)鍵字: ST FDA 代碼 ADI

(全球TMT2022年10月11日訊)數(shù)字網(wǎng)絡(luò)集成商STL宣布與Vocus Group合作開(kāi)展西澳大利亞的地平線項(xiàng)目。在此次合作中,STL將為Vocus的國(guó)際資本網(wǎng)絡(luò)擴(kuò)展計(jì)劃提供高強(qiáng)度光纖電纜。這項(xiàng)交易加強(qiáng)了STL與V...

關(guān)鍵字: 光纖網(wǎng)絡(luò) ST 電纜 GROUP

馬斯克(Elon Musk)旗下的SpaceX公司已開(kāi)始在日本提供運(yùn)用衛(wèi)星通信技術(shù)的互聯(lián)網(wǎng)服務(wù)“Starlink(星鏈)”。日本是首個(gè)展開(kāi)該服務(wù)的亞洲國(guó)家。該公司打算用該服務(wù)來(lái)抓住日本的山區(qū)和離島等確保通信手段的需求。官...

關(guān)鍵字: LINK ST SPACEX 互聯(lián)網(wǎng)

Meta在年度大會(huì)上發(fā)布新款VR頭盔Quest Pro,售價(jià)1500美元。Quest Pro使用手機(jī)內(nèi)部和周?chē)臄z像頭來(lái)捕捉面部運(yùn)動(dòng),它可以實(shí)時(shí)將這些捕捉到的信息應(yīng)用于用戶的頭像和表情。 (全球企業(yè)動(dòng)態(tài))...

關(guān)鍵字: VR ST 手機(jī) 攝像頭

Meta Quest Pro定于本月25日面市,定價(jià)1500美元。零售包裝內(nèi)含頭戴裝置,Quest Touch Pro手柄,充電底座,壓感筆尖(手柄附件),部分遮光罩(另有全遮光罩可選)。開(kāi)發(fā)單位宣稱Meta Quest...

關(guān)鍵字: ST AN 傳感器 GB

CPP開(kāi)發(fā)者

237 篇文章

關(guān)注

發(fā)布文章

編輯精選

技術(shù)子站

關(guān)閉