简体   繁体   English

C ++映射的线程同步

[英]Thread synchronisation for C++ map

I'm creating a multithreaded c++ program using pthread (c++98 standard). 我正在使用pthread(c ++ 98标准)创建一个多线程的c ++程序。

I have a std::map that multiple threads will access. 我有一个多线程将访问的std :: map。 The access will be adding and removing elements, using find, and also accessing elements using the [] operator. 访问将使用find添加和删除元素,并使用[]运算符访问元素。

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. 我知道使用[]运算符进行读取,甚至使用它修改元素是线程安全的,但其余操作则不是。

First question: do I understand this correctly? 第一个问题:我能正确理解吗?

Some threads will just access the elements via [], while others will do some of the other operations. 有些线程只能通过[]访问元素,而其他线程则会执行其他一些操作。 Obviously I need some form of thread synchronisation. 显然我需要某种形式的线程同步。

The way I see this should work is: - While no "write" operation is being done to the map, threads should all be able to "read" from it concurrently. 我认为这应该工作的方式是: - 虽然没有对地图进行“写入”操作,但线程应该能够同时从它“读取”。 - 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. - 释放锁后,所有线程都应该能够自由读取。

The main question is: what thread synchronisation methods can I use to achieve this behaviour? 主要问题是:我可以使用哪些线程同步方法来实现此行为?

I have read about mutex, conditional variables and semaphores, and as far as I can see they won't do excatly what I need. 我已经读过有关互斥,条件变量和信号量的内容,据我所知,他们不会做我需要的东西。 I'm familiar with mutex but not with cond. 我熟悉互斥,但不熟悉cond。 variables or semaphores. 变量或信号量。

The main problem I see is that I need a way of locking threads until something happens (the write operation ends) without those threads then locking anything in turn. 我看到的主要问题是我需要一种锁定线程的方法,直到某些事情发生(写操作结束),然后这些线程依次锁定任何东西。 Also I need something like an inverted semaphore, that blocks while the counter is more than 1 and then wakes when it is 0 (ie no read operation is being done). 此外,我需要类似倒置信号量的东西,当计数器大于1时阻塞,然后当它为0时唤醒(即没有进行读取操作)。

Thanks in advance. 提前致谢。

PS It's my first post. PS这是我的第一篇文章。 Kindly indicate if I'm doing something wrong! 请指出我做错了什么!

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? 我能正确理解吗?

Well, what you've said isn't quite true. 那么,你所说的并不完全正确。 Concurrent readers can use [] to access existing elements, or use other const functions (like find , size() ...) safely if there's no simultaneous non- const operations like erase or insert mutating the map<> . 并发读者可以使用[]来访问现有元素,或者安全地使用其他const函数(例如findsize() ...), 如果没有同时的非const操作,例如eraseinsert变异map<> Concurrent threads can modify different elements, but if one thread modifies an element you must have some synchronisation before another thread attempts to access or further modify that specific element. 并发线程可以修改不同的元素,但是如果一个线程修改了一个元素,则在另一个线程尝试访问或进一步修改该特定元素之前,必须先进行一些同步。

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. - 释放锁后,所有线程都应该能够自由读取。

That's not quite the way it works... for writers to be able to 'wait until all "read" operations have completed' , the reader(s) need to acquire a lock. 这不是它的工作方式......为了使作者能够“等到所有”读取“操作完成” ,读者需要获得锁定。 Writers then wait for that same lock to be released, and acquire it themselves to restrict other readers or writers until they've finished their update and release it. 编写者然后等待同一个锁被释放,并自己获取它以限制其他读者或作者,直到他们完成更新并释放它。

what thread synchronisation methods can I use to achieve this behaviour? 我可以用什么线程同步方法来实现这种行为?

A mutex is indeed suitable, though you will often get higher performance from a reader-writer lock (which allows concurrent readers, some also prioritorise waiting writers over further readers). 一个互斥锁确实是合适的,尽管你经常会从读写器锁中获得更高的性能(允许并发读者,有些人还会优先考虑等待作者而不是其他读者)。 Related POSIX threads functions include: pthread_rwlock_rdlock , pthread_rwlock_wrlock , pthread_rwlock_unlock etc.. 相关的POSIX线程函数包括: pthread_rwlock_rdlockpthread_rwlock_wrlockpthread_rwlock_unlock等。

To contrast the two approaches, with readers and writers using a mutex you get serialisation something like this: 为了对比这两种方法,使用互斥锁的读者和编写者可以得到类似这样的序列化:

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...

With a read-write lock, it might be more like this (notice the first two readers run concurrently): 使用读写锁,可能更像是这样(注意前两个读取器并发运行):

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...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM