(CopyOnWrite)在多线程环境中的陷阱(一) (CopyOnWrite)在多线程环境中的陷阱(二) 其实这个bug并不发生在: 当UI主线程使用strLog中的字符串更新Edit, 同时AddText被其他线程调用进行m_strStore +=操作 这种情况, 而是发生在: 当UI主线程调用strLog中的析构函数, 同时AddText被其他线程调用进行m_strStore +=操作 这种时候。 为什么会发生这种情况了? 首先我们看当UI主线程调用strLog中的析构函数的情况: 大概的程序流程是: a1. 检查引用计数是否大于1 a2. 是, 引用计数减一,返回 a3. 否则,释放字符串 注意,1-2步并不是一个原子操作,而且读取引用计数的时候并没有临界端保护。 然后我们再看AddText被其他线程调用进行m_strStore +=操作 时发生的情况 b1. 判断引用计数是否大于1 b2. 是,引用计数减一,分配新字符串并指向之 b3. 否,在当前字符串继承上进行+=操作,如果空间不够,可能也要重新分配字符串。 同样,1-2步并不是一个原子操作,而且读取引用计数的时候并没有临界端保护。 这样考虑如下的执行序列: a1, //发现引用计数为2 b1 //发现引用计数为2 b2 //引用计数减一,分配新字符串并指向之 a2 //引用计数减一,返回 在执行完b2的时候,引用计数已经为1了,但a线程接下来运行a2的时候,引用计数再次减一,变为0。同时,这块内存已经成为”孤魂野鬼“,不在被任何一个std::string对象所拥有,造成内存泄漏。 我们现在发现了问题,那么如何改正这个错误呢? (CopyOnWrite)在多线程环境中的陷阱(四) 
|