O
O
Oleg Shevelev2016-04-21 00:13:38
go
Oleg Shevelev, 2016-04-21 00:13:38

How to remove from map in a loop if the loop is protected via RWMutex.RLock() in Golang?

We have:
1. map which is protected through RWMutex
2. when we read data from map we set RLock(), then we release it through RUnlock()
3. when we write to map we set Lock, then we release it through Unlock()
What to do if we read map through a loop and at some point we understand that we no longer need this element in the map and can and should be removed? In this case, the cycle is already protected through RLock (read-only, not write-only).
Options:
1. release RLock(), take Lock()
2. somehow turn RLock() into Lock() in some other way
3. write the keys of the elements to be removed in slice and go through them in a separate loop at the end blocking the map through Lock() . Minus - you have to wait, but then the elements are removed in a pack.
4. do go l.delete(key) and put the deletion with Lock/Unlock into this function? Cons - there can be a rise in the number of goroutines equal to the number of elements. At the same time, if there is a concurrent reading of this map with the same go l.delete(key), then we multiply by the number of concurrent threads that read this map, plus a handful that has accumulated in the time until the element has managed to be deleted.
An example code in a hurry here: https://play.golang.org/p/5od76B-GVg
Asked a similar question in English https://stackoverflow.com/questions/36754838/is-it... and they write that delete is like this but it is necessary to protect it through Lock, but it’s not clear how to do deletion effectively when reading map in a loop.
Links to the source code are welcome, as well as just opinions.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
N
Nikita, 2016-04-21
@bitver

Judging by the Wangyu code, you are not doing what you want, is it not a Worker pool that is normal? There are plenty of them on the net, look for them.
If you need the current code to work, then yes, you need to lock delete too without fail and lock RLock() when reading (not outside the loop, but right when reading), if outside the loop, then the slice option seems to be suitable.
I played a little, this option is prettier, IMHO. But there is one "but", for range you can't go through this.
https://play.golang.org/p/CeGHYK5nBr

G
GeckoGreen, 2016-04-28
@GeckoGreen

Option 4 is almost the same as 3, because before RUnlock() all routines will be in hibernation, and after that they will begin to compete for mutex capture. Therefore, the third is better than the fourth.
Option 2 can be implemented only by implementing your own mutex, which is not the best option. You can, of course, use option 1, but there is pandemonium with mutexes and therefore it can turn out to be slower and not very efficient. Option 5 is possible. If the deletion will occur only in 1 routine, then you can make a new map, and after the scan, replace the variable. But the result, of course, will be after the end of the cycle.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question