作者lovejomi (JOMI)
看板C_and_CPP
標題[問題] thread safe 觀念請教
時間Sun Jun 3 00:07:22 2018
突然想說包裝一個thread safe的vector
最單純的想法就是把vector常用的api
每一個都用lock_guard<mutext>(mMutex) 保護
但仔細想一個情況
vector的operator[]是回傳 reference的.
reference operator[]( size_type pos );
假設
thread1 寫 Foo f; f = mVec[0]; // 走 operator=(const Foo&)
thread2 寫 無數次的 mVec.push_back(foo);
這時候 thread1的複製動作 我根本無法保證當下reference的object是valid的
我認為很有可能thread2在push_back的時候造成vector的realloc 所以thread1 就read到
莫名其妙的數值
(這邊也想問, "讀取" heap上面而非write 就算被deleted,
會有可能造成除了讀到錯的數值以外的行為產生嗎? 例如crash)
我所能想到的變成
1. 不提供operator[]了 而是提供SetAt(int index, Foo& out) 讓set的動作我內部完全
lock保護
2. 我vector class expose我的mutex給外面用的人lock...但這樣變得一點thread safe
的感覺都沒了
這兩個想法 說真的我從來沒看過... 是我多想了嗎?
還是大多情況就是by value return就好不要弄成reference.
有沒有在探討這件事的文章可以讓我觀念更清楚一點
謝謝
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 27.242.100.195
※ 文章網址: https://webptt.com/m.aspx?n=bbs/C_and_CPP/M.1527955644.A.876.html
1F:→ bluesoul: 不要提供reference 06/03 00:10
2F:→ bluesoul: 讀到錯的東西,資料就亂七八糟了 06/03 00:11
3F:推 Schottky: 讀到錯的東西,沒crash比當場crash更慘一萬倍吧 06/03 00:15
4F:→ Schottky: 接下來就是要抓不知何時發生、為何會發生的古怪bug了 06/03 00:16
5F:→ lovejomi: stl就提供ref想說終於原版,找一個好的thread safe寫法. 06/03 01:20
6F:→ lovejomi: .. 06/03 01:20
7F:→ firose: 問題是 ctor 有 by value 的版本嗎? 06/03 08:08
8F:→ firose: copy ctor 06/03 08:10
9F:→ firose: 搞錯了抱歉 請跳過我說的 06/03 08:12
10F:推 lightyen: 同一樓 不要提供reference 06/03 09:15
11F:→ lightyen: mutex直接用就好了 過度的包裝反而不容易維護 06/03 09:19
12F:推 shadow0326: 通常mutex保護的是存取vector的那段code,而不是把整 06/03 11:02
13F:→ shadow0326: 個vector包起來 06/03 11:02
14F:→ shadow0326: STL container都有iterator或ref invalidate的問題 06/03 11:03
15F:→ shadow0326: 全保護起來就變得超難用,還不如不用 06/03 11:04
16F:推 littleshan: C++ container 提供了 ref 就無法做到 thread safe 06/03 16:27
17F:→ littleshan: 如果你想要兩者兼得就不能用 C++,改用 Rust 吧 06/03 16:28
18F:→ littleshan: 另一個解法是把 ref 改成 proxy object 06/03 16:29
19F:→ littleshan: 只是效能會變得超級慢 06/03 16:29
20F:推 obj: 應該是操作vector的地方用mutex保護起來 06/07 23:46