Unfortunately, that's not how Go maps work. You'll still get races unless 
you synchronize even "read-only" maps.

On Tuesday, February 22, 2022 at 11:59:37 PM UTC-6 ren...@ix.netcom.com 
wrote:

> The top level map locks doesn’t matter - it is write once at init and read 
> only after. 
>
> On Feb 22, 2022, at 11:51 PM, Jason E. Aten <j.e....@gmail.com> wrote:
>
> You have not synchronized access to the top level mapLocks map itself.  
> Thus you will get races. You need to have a mutex that you lock before you 
> access mapLocks; not just the maps that are inside it.
>
>
> I would also recommend being a little object oriented about this design, 
> putting each map inside its own struct, and make a set of accessor methods 
> that Lock() and defer Unlock() on a mutex that protects the maps inside.  
> Read code like this for an idea of what I mean. 
> https://github.com/glycerine/atomicmap/blob/master/amap.go
>
> On Tuesday, February 22, 2022 at 9:55:04 PM UTC-6 ren...@ix.netcom.com 
> wrote:
>
>> Something else is wrong - because marketMaps is read-only after init… so 
>> unless you have some other code - that is not the map causing the panic.
>>
>> My guess is because you are returning the map from ReadMaps (or RWMaps) 
>> that you are using THAT map by multiple threads outside the lock (the map 
>> is a reference not a copy) and that is causing the panic.
>>
>> On Feb 22, 2022, at 9:39 PM, Zhaoxun Yan <yan.z...@gmail.com> wrote:
>>
>> Hi guys!
>> I know this is quite challenging, but it makes sense in io-heavy 
>> applications.
>>
>> I need to test the responsiveness of different financial future quotation 
>> sources. They return the quotations spontaneously, and my program respond 
>> to each one of the CGO call backs from the quotation library and save the 
>> current prices. Meanwhile, a timer ensures to check the current quotations 
>> of each available sources. And obviously, it raised up a panic due to 
>> synchronization of maps on the call of ReadMaps function. Unfortunately 
>> this came up occasionally and `go build -race` cannot raise the problem.
>>
>> Here is a piece of the code, only the read/write part:
>>
>>
>> ------------------------------------------------------------------------------------------
>>
>> // Please Ignore SyChan to alert the timer that all available sources are 
>> collected 
>> var SyChan chan int = make(chan int, 3)
>>
>> // Make up a map of 5 mutex locks and a map of 5 data structs, indexed by 
>> 1-5
>> var marketMaps = make(map[int]map[string]Market)
>> var mapLocks = make(map[int]*sync.Mutex)
>>
>> // quotation data
>> type Market struct {
>>         Price     float64 `json:"price"`
>>         Timestamp string  `json:"timestamp"`
>> }
>>
>> func init() {
>>         for i := 1; i <= 5; i++ {
>>                 mapLocks[i] = new(sync.Mutex)
>>                 marketMaps[i] = make(map[string]Market)
>>         }
>> }
>>
>> //Make sure that for each source, R/W has no race, only took place as 
>> acquiring the particular Mutex inside the map of Mutex.
>> func RWMaps(targetnum int, purpose, future_id string, market Market) 
>> map[string]Market {
>>     
>>         mapLocks[targetnum].Lock()
>>         defer mapLocks[targetnum].Unlock()
>>
>>         if purpose == "update" {//The original Write part
>>                 marketMaps[targetnum][future_id] = market
>>                    return nil
>>         } else { //The read part, has been extracted to ReadMaps
>>                 SyChan <- 1
>>                 return marketMaps[targetnum]
>>         }
>> }
>>
>> //Here is why I use map: not all 5 sources must be available, some may 
>> have connection failure and would be marked as false in Usable[i] , i being 
>> its source No.
>> func ReadMaps(targetnum, checkTime int) map[string]Market {
>>         mapLocks[targetnum].Lock()
>>         defer mapLocks[targetnum].Unlock()
>>         if Usable[targetnum] {
>>                 fmt.Printf("%d-th time to read source %d \n", checkTime, 
>> targetnum)
>>         }
>>         SyChan <- 1
>>         return marketMaps[targetnum]
>> }
>>
>>
>> --------------------------------------------------------------------------------------------------
>>
>> My problem is :
>>
>> I still want to keep the map structure, rather than naming mutex1, 
>> mutex2, mutex3,... , marketmsg1, marketmsg2, .... And obviously if the map 
>> prohibits reading or writing spontaneously, the writing by each usable 
>> sources is not fair - They must line up as one queue (like using one Mutex 
>> for all instead) hence the checking of quotation snap on a time-spot is 
>> defected.  I have also checked the sync.Map and it seems to allow 
>> spontaneous reading but still prohibits spontaneous writing.
>>
>> My instinct is to make map on the pointer of structs. On that way, if I 
>> could use sync.Map, both the read and write function only read the map to 
>> find the address of data structs, then writing several data structs on the 
>> same time won't violate the rule on sync.Map.
>>
>> Is the proposal above legitimate? And anyone could come up a test case to 
>> mimic the quotation sources? Because with CGO to complicate the program, go 
>> cannot raise the race problem on -race check, and the successful build can 
>> panic occasionally.
>>
>> Thanks in advance! 
>>
>> -- 
>> You received this message because you are subscribed to the Google Groups 
>> "golang-nuts" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to golang-nuts...@googlegroups.com.
>> To view this discussion on the web visit 
>> https://groups.google.com/d/msgid/golang-nuts/9a981200-23f8-4dae-8c20-7acfdcd3f2fcn%40googlegroups.com
>>  
>> <https://groups.google.com/d/msgid/golang-nuts/9a981200-23f8-4dae-8c20-7acfdcd3f2fcn%40googlegroups.com?utm_medium=email&utm_source=footer>
>> .
>>
>>
>> -- 
> You received this message because you are subscribed to the Google Groups 
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to golang-nuts...@googlegroups.com.
>
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/golang-nuts/215a541a-ecc6-49e2-9427-81f62c5b168en%40googlegroups.com
>  
> <https://groups.google.com/d/msgid/golang-nuts/215a541a-ecc6-49e2-9427-81f62c5b168en%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/0b709930-8fbb-4fce-8cdf-0cf3bb401d22n%40googlegroups.com.

Reply via email to