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+unsubscr...@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.