gpt4 book ai didi

c++ - C++ map 的线程同步

转载 作者:可可西里 更新时间:2023-11-01 18:35:41 25 4
gpt4 key购买 nike

我正在使用 pthread(c++98 标准)创建多线程 c++ 程序。

我有一个 std::map 可以被多个线程访问。访问将添加和删除元素,使用查找,还使用 ​​[] 运算符访问元素。

我知道使用 [] 运算符读取,甚至用它修改元素是线程安全的,但其余操作不是。

第一个问题:我理解正确吗?

一些线程将仅通过 [] 访问元素,而其他线程将执行一些其他操作。显然我需要某种形式的线程同步。

我认为这应该起作用的方式是:- 虽然没有对映射进行“写入”操作,但线程应该都能够同时从中“读取”。- 当一个线程想要“写”到映射时,它应该设置一个锁,这样就没有线程开始任何“读”或“写”操作,然后它应该等到所有“读”操作都完成,此时它将执行操作并释放锁。- 释放锁后,所有线程都应该可以自由读取。

主要问题是:我可以使用哪些线程同步方法来实现此行为?

我读过有关互斥量、条件变量和信号量的内容,据我所知,它们并不能完全满足我的需要。我熟悉 mutex 但不熟悉 cond。变量或信号量。

我看到的主要问题是我需要一种锁定线程的方法,直到发生某些事情(写操作结束),而不是那些线程依次锁定任何东西。我还需要像倒置信号量这样的东西,它在计数器大于 1 时阻塞,然后在它为 0 时唤醒(即没有进行读取操作)。

提前致谢。

附言这是我的第一篇文章。如果我做错了什么,请指出!

最佳答案

I understand that reading using the [] operator, or even modifying the elements with it is thread safe, but the rest of the operations are not.

Do I understand this correctly?

嗯,你说的不太对。并发读者可以使用[]访问现有 元素,或使用其他 const函数(如 findsize() ...)安全如果没有同时非 const类似 erase 的操作或 insert变异 map<> .并发线程可以修改不同的元素,但如果一个线程修改了一个元素,则在另一个线程尝试访问或进一步修改该特定元素之前,您必须进行某种同步。

When a thread wants to "write" to the map, it should set a lock so no thread starts any "read" or "write" operation, and then it should wait until all "read" operations have completed, at which point it would perform the operation and release the locks. - After the locks have been released, all threads should be able to read freely.

这不是它的工作方式......对于能够“等待所有“读取”操作完成”的写入者,读取者需要获取锁。然后写入者等待同一个锁被释放,并自己获取它以限制其他读者或写入者,直到他们完成更新并释放它。

what thread synchronisation methods can I use to achieve this behaviour?

互斥确实是合适的,尽管您通常会从读写器锁中获得更高的性能(它允许并发读取器,有些还优先于等待写入器而不是其他读取器)。相关的 POSIX 线程函数包括: pthread_rwlock_rdlock , pthread_rwlock_wrlock , pthread_rwlock_unlock 等..

为了对比这两种方法,读者和作者使用互斥锁,你得到的序列化是这样的:

THREAD   ACTION
reader1 pthread_mutex_lock(the_mutex) returns having acquired lock, and
thread starts reading data
reader2 pthread_mutex_lock(the_mutex) "hangs", as blocked by reader1
writer1 pthread_mutex_lock(the_mutex) hangs, as blocked by reader1
reader1 pthread_mutex_unlock(the_mutex) -> releases lock
NOTE: some systems guarantee reader2 will unblock before writer1, some don't
reader2 blocked pthread_mutex_lock(the_mutex) returns having acquired lock,
and thread starts reading data
reader1 pthread_mutex_lock(the_mutex) hangs, as blocked by reader2
reader2 pthread_mutex_unlock(the_mutex) -> releases lock
writer1 blocked pthread_mutex_lock(the_mutex) returns having acquired lock,
and thread starts writing and/or reading data
writer1 pthread_mutex_unlock(the_mutex) -> releases lock
reader1 blocked pthread_mutex_lock(the_mutex) returns having acquired lock,
and thread starts reading data
...etc...

有了读写锁,它可能更像是这样(注意前两个读者并发运行):

THREAD   ACTION
reader1 pthread_rwlock_rdlock(the_rwlock) returns having acquired lock, and
thread starts reading data
reader2 pthread_rwlock_rdlock(the_rwlock) returns having acquired lock, and
thread starts reading data
writer1 pthread_rwlock_wrlock(the_rwlock) hangs, as blocked by reader1/2
reader1 pthread_rwlock_unlock(the_rwlock) -> releases lock
reader1 pthread_rwlock_rwlock(the_rwlock) hangs, as pending writer
reader2 pthread_rwlock_unlock(the_rwlock) -> releases lock
writer1 blocked pthread_rwlock_wrlock(the_rwlock) returns having acquired lock,
and thread starts writing and/or reading data
writer1 pthread_rwlock_unlock(the_rwlock) -> releases lock
reader1 blocked pthread_rwlock_rwlock(the_rwlock) returns having acquired lock,
and thread starts reading data
...etc...

关于c++ - C++ map 的线程同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30889181/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com