- 主题:Qt 的 cow 其实不是线程安全的对吧。
比如我有个
QList data;
进程 A 正在执行:
while (true) {
data << e;
}
而进程 B 正在进行这样的操作:
QList dataB = data;
dataB << e;
在执行 `dataB << e;` 这一行时,QList 会执行 detach() clone data 。。会失败吗?
--
FROM 110.81.41.*
为什么呢?
我看了一下源代码,QSharedData::detach() 和 QList 的复制构造函数都没有加锁的代码啊。
【 在 hgoldfish (老鱼) 的大作中提到: 】
: 比如我有个
: QList data;
: 进程 A 正在执行:
: ...................
--
FROM 110.81.41.*
问题是我看过代码以后,怎么感觉这个说法不是那么可靠。
【 在 dormouseBHU (dormouseBHU) 的大作中提到: 】
: Many Qt classes are reentrant, but they are not made thread-safe, because making them thread-safe would incur the extra overhead of repeatedly locking and unlocking a QMutex. For example, QString is reentrant but not thread-safe. You can safely acces
--
FROM 110.81.41.*
引用计数本身是 atomic,所以没问题。
但 detach() 时要做一次复制啊。这个复制如果碰到另外一个线程正在插入数据,那怎么办?
【 在 flybb (倒影) 的大作中提到: 】
: 构造时不能有别的线程同时使用
: detach时可以其他线程同时使用,基于引用计数实现
--
FROM 110.81.41.*
有道理!我脑子抽了!
【 在 flybb (倒影) 的大作中提到: 】
: 另外一个线程插入数据前 要先detach
: 等于两个线程同时从原来的d里复制数据出来,所以线程安全
--
FROM 110.81.41.*
跟 stl 同样的语义,如果不想多复制一遍内存就用 shared_ptr<> 然后自己再加锁同步。
【 在 dormouseBHU (dormouseBHU) 的大作中提到: 】
: 确实线程安全,但是多复制了一遍数据,还多删除了一遍数据,感觉碰到这个场景,效率很低啊。
--
FROM 112.47.122.*
高并发时碰到这种情况就只维护一份数据,用 QSharedPointer<> 来维护数据的生命周期。问题不大。
【 在 libgcc (乞讨积分,求施舍,长期有效) 的大作中提到: 】
: 高并发的话倒是很正常
: 不过本来就该加锁
--
FROM 124.72.118.*