如何正确处理带有循环的互斥锁
How do handle a mutex with a loop correctly?
这主要是一个理论问题,所以请不要怪我提出这个问题。
现在,我读到递归互斥锁是邪恶的。我知道为什么。
然而,假设你有这样的小情况:
LockMutex();
for(ListIterator it = List.begin(); it != List.end(); ++it) {
//doStuff, which might possibly alter the List contents
}
UnlockMutex();
对很多人来说似乎很熟悉,我相信。现在最大的问题是,如何正确处理这种情况?
在对它进行一些思考并且不使用递归互斥锁(这是邪恶的)之后,唯一可能的选择是这样做:
LockMutex();
for(ListIterator it = List.begin(); it != List.end(); ++it) {
UnlockMutex();
//doStuff, which might possibly alter the List contents
LockMutex();
}
UnlockMutex();
现在,"递归互斥锁是邪恶的"的原因之一是,它们需要额外的开销来记住谁拥有锁以及锁的频率……每次迭代都没有额外的开销来解锁和重新锁定互斥锁吗?
此外,如果另一个线程在互斥锁未锁定的情况下访问列表,并且改变了迭代所针对的元素,会发生什么?可能会删除我们当前所在的元素,实质上使迭代器无效,从而导致非常严重的错误?
我知道在迭代期间锁定整个列表是一个可怕的瓶颈,但我认为对于大多数轻量级应用程序来说,与允许第二个线程在我不注意的时候扰乱列表而导致整个应用程序崩溃的风险相比,这是我能够忍受的。
我也看了ReaderWriter-Locks,但问题仍然是一样的。从技术上讲,只要循环的内容可能改变列表(这很难预见,特别是在使用多态性的情况下),就需要获得对列表的写锁,这再次意味着,此时没有其他线程可以访问列表。并且迭代器失效的问题仍然存在。
所以,是的,有什么想法或智慧的话给我吗?
//doStuff,这可能会改变List的内容
这也意味着你的迭代器可能不再有效。所以我认为设置互斥锁是你的上下文中的第二个问题。
是的,如果你可以用一个有效的迭代器遍历列表,那么如果外部访问会以一种使迭代器无效的方式修改列表,你就必须保护完整的列表。我相信您不能保证对列表的外部访问将使您的迭代器保持有效。互斥锁必须在你的循环中。
但是首先要记住,在互斥锁保护的循环中访问列表必须保证迭代器的有效性。
- 在 for 循环中处理复杂的发送 recv 消息
- arm-none-eabi-g++ 不能使用 -flto 正确处理弱别名
- 如何避免 boost 的野兽body_limit错误并正确处理大消息
- 如何正确处理渲染大小为 >= 2B 的 utf-8 字符?
- 是否正确处理了此代码异常?
- 为什么 CSpinButtonCtrl 不能正确处理大于 1000 的数字?
- 自定义迭代器:如果 a 和 b 的行为不同,如何正确处理距离计算和相等比较
- 编译器在 C/C++ 中通过指针调用函数时如何正确处理 ABI
- 如何在 Python 3 中正确处理用于嵌入的字符串
- 如何正确处理OpenSSL错误(BIO)
- 为什么我的模板专业检查不足以正确处理相应的类型
- 正确使AI循环正确
- 在子类过程中正确处理WM_PASTE
- 如何正确处理此SFINAE
- 如何在 c++ 中正确处理常量字符*
- 如何在多线程程序中使用 boost::asio 正确处理 fork()
- 类的静态实例无法在程序退出时正确处理资源删除
- 正确处理 QtT并发"infinite"循环
- 如何正确处理带有循环的互斥锁
- 如何正确处理 win32 GUI 消息循环