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ù)閱讀解法二!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)。比如:分段加鎖
,減少一點(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ú)法解決。
可能
的偽共享帶來(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)論!標(biāo)普500指數(shù)今年迄今為止下跌22.7%,但高盛(Goldman Sachs)策略師認(rèn)為估值依然太高。摩根士丹利旗下的Morgan Stanley Wealth Management稱,面對(duì)高通脹環(huán)境下的利率大幅上升,股...
關(guān)鍵字: DMA MANAGEMENT 高通 ST(全球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)