作者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/cn.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