Map keys read and reWrite sync is not working for socket programming

Hello, I’m a bit new on Go, please I need your help, I’m working for a year in a socket programming wrote on PHP, and was working, but I heard a good comments about “Go” and I’ve decide migrated my project on this languaje, but I have this problem that I’ve describe…

I need to capture a lot of data in few ms, 0,8 ms and each frame ethernet has 1358 Bytes, and also I need to open the header of this packet and analize it…
each frame has 7 headers , diferents all, and I need to store this data into a “Map Key array”, but when I try to analyze all data they send me a problem with read and write map Key data

######################################################
2017/07/17 16:57:48 Old map: map[1fff:0 4011:a 4001:c 4000:c]
2017/07/17 16:57:48 Old map: map[4001:c 4000:c 1fff:0 4011:a]
fatal error: concurrent map read and map write

goroutine 820 [running]:
runtime.throw(0x1112bc, 0x21)
/usr/local/go/src/runtime/panic.go:596 +0x70 fp=0x1053095c sp=0x10530950
runtime.mapaccess2(0xf43a8, 0x104703e0, 0x106d12a0, 0x106d12b8, 0x104d4058)
/usr/local/go/src/runtime/hashmap.go:377 +0x248 fp=0x1053097c sp=0x1053095c
reflect.mapaccess(0xf43a8, 0x104703e0, 0x106d12a0, 0x104703e0)
/usr/local/go/src/runtime/hashmap.go:1128 +0x2c fp=0x10530994 sp=0x1053097c
reflect.Value.MapIndex(0xf43a8, 0x104703e0, 0x15, 0xf35b0, 0x106d12a0, 0x98, 0xf35b0, 0x106d12b8, 0x98)
/usr/local/go/src/reflect/value.go:1052 +0xc8 fp=0x105309d4 sp=0x10530994
fmt.(*pp).printValue(0x104e4000, 0xf43a8, 0x104703e0, 0x15, 0x76, 0x0)
/usr/local/go/src/fmt/print.go:752 +0xd0c fp=0x10530acc sp=0x105309d4
fmt.(*pp).printArg(0x104e4000, 0xf43a8, 0x104703e0, 0x76)
/usr/local/go/src/fmt/print.go:682 +0x1c4 fp=0x10530b0c sp=0x10530acc
fmt.(*pp).doPrintln(0x104e4000, 0x10530fd4, 0x2, 0x2)
/usr/local/go/src/fmt/print.go:1138 +0x8c fp=0x10530b48 sp=0x10530b0c
fmt.Sprintln(0x10530fd4, 0x2, 0x2, 0x106d1280, 0x10530e9c)
/usr/local/go/src/fmt/print.go:264 +0x3c fp=0x10530b70 sp=0x10530b48

##############################################################

I’ve read a lot of post relationship with map key on Go, and for Go solved used a library called sync, but when I use that the program working, but didn’t analyze any data is like blocked all key maps in my program,

I’ve use Map Key sync as this way:

"sync"

var (
PidCCerr = make(map[string]string)
PidCCerrLock = &sync.RWMutex{}
PidCCerrSequence int
)

// New pids value
var PidNew = map[string]string{}

and the I generate a switch for read all frame and get all headers,

if a heders is the same as old header , I need to remplace it with a new data , for this reason I delete a value of key map and re write it…

################################################

func CompareKeyValue(PIDOld string) {

	//Extract Value from Map[key] , if value exists??
    CCerr, ok := PidCCerr[PIDOld]
    if ok {
    log.Println("*********************** " )
    log.Println("Found Ccerr Old " ,CCerr )
	log.Println("Found PID " ,PIDOld )
    log.Println("*********************** " )
    //log.Println("Pid New: ", CCerrNew)
            //fmt.Println("Substract: ", int (CCerrNew - value)
    } else {
            log.Println("key not found")
    }

}

####################################################

if has the same value I’ ve delete it

switch i {
case 0:

            log.Println("############################################")
            log.Println("############################################")
            log.Println("Begin ")
            log.Println("Number i = ",i)
            SplitLine := strings.Split(SplitData[i],"|")
            Split := SplitLine[0]
            
            PID,Scrambled,CCerr := GetHeaderTS(Split,8,16)
           
           log.Println("Lock and Unlock ")
            PidCCerrLock.RLock()
            defer PidCCerrLock.RUnlock()
            CompareKeyValue(PID) 
            PidCCerrLock.RLock()
            
            //time.Sleep(1 * time.Millisecond)
            PidCCerrLock.RLock()
            defer PidCCerrLock.RUnlock()
            log.Println("Old map:", PidCCerr)
            delete(PidCCerr, PID);
            //time.Sleep(1 * time.Millisecond)
            PidCCerrLock.Lock()
            defer PidCCerrLock.Unlock()
            PidCCerr[PID] = CCerr   
            log.Println("New map:", PidCCerr)
            //Header := Split[8:16]
            //PidCCerrLock.RUnlock()
            log.Println("Pid 0 data Hexa ",PID)
            log.Println("is Scrambled?? ",Scrambled)
            log.Println("CCerr => ",CCerr)
                        
            i+=11
            log.Println("END ")
        case 11:
            //log.Println("Number i = ",i)

            

            log.Println("############################################")
            log.Println("Begin ")
            log.Println("map:", PidCCerr)
            SplitLine := strings.Split(SplitData[i],"|")
            Split := SplitLine[0]

            
            f = len(Split) - 8
            l = f + 8
            PID,Scrambled,CCerr := GetHeaderTS(Split,f,l)
           
            
           log.Println("Lock and Unlock ")
            PidCCerrLock.RLock()
            defer PidCCerrLock.RUnlock()
            CompareKeyValue(PID) 
            PidCCerrLock.RLock()
            
            PidCCerrLock.RLock()
            defer PidCCerrLock.RUnlock()
            log.Println("Old map:", PidCCerr)
            delete(PidCCerr, PID);
            PidCCerrLock.Lock()
            defer PidCCerrLock.Unlock()
            PidCCerr[PID] = CCerr   
            log.Println("New map:", PidCCerr)
            //PidCCerrLock.RUnlock()
            log.Println("Pid 1 data Hexa ",PID)
            log.Println("is Scrambled?? ",Scrambled)
            log.Println("CCerr => ",CCerr)
            
            i+=12
            log.Println("END ")
            log.Println("############################################")

what I did wrong with sync library?, why my program can’t read and write any data on my array map key strings.?, please help me to fix that…

fatal error: concurrent map read and map write

This usually means that the map is accessed concurrently outside any locked code block. Unfortunately, the stack trace does not reveal the line whithin your code that triggers the error.

Run your code with the -race flag to get more information about this race condition.

The code posted here is incomplete, so it is difficult to reason about it. It would appear that

CCerr, ok := PidCCerr[PIDOld]

at the beginning of func CompareKeyValue is not guarded by any lock (but then I cannot tell in which context CompareKeyValue is called - maybe this code is inside a lock already). I also wonder why you are doing multiple RLock() calls on the same mutex within the same code block - one RLock() at the beginning would seem sufficient (but again, I don’t have all of the code, so maybe there is a reason for the way you do it).

If nothing helps, maybe you could try reducing the code so that you can post a runnable version of the code that still replicates the race condition.

1 Like

You are doing a bunch of these in sequence:

PidCCerrLock.Lock()
defer PidCCerrLock.Unlock()

The first time this happens it’s fine. It means lock the the mutex and unlock it when the function returns. The next time however you will deadlock, because the mutex is already locked and you are attempting to lock it again. Remember, defers only run when the function returns.

1 Like

Thanks for your answer Chris, on yesterday I’ve started use C++, but I think if google made “go”, should be working… :smile: , let me try with this flag and also I’ll try posting a little version, but is difficult to replicate the same condition because the program is a sniffer that capture a multicast-TS, but let me check what can I do.

thanks infinitely again for your help.

Thanks for your answer Jakob, if I understood, that mean, let me get for you an example , if I need to
read , delete or write a map key value , should be like this way?
###########################################
1- read key map from fuction “CompareKeyValue”
###########################################

            PidCCerrLock.RLock()
            CompareKeyValue(PID)

func CompareKeyValue(PIDOld string) {

	//Extract Value from Map[key] , if value exists??
    CCerr, ok := PidCCerr[PIDOld]
    if ok {
    log.Println("*********************** " )
    log.Println("Ccerr Old " ,CCerr )
	log.Println("PID " ,PIDOld )
    log.Println("*********************** " )

defer PidCCerrLock.RUnlock()
        } else {
                log.Println("key not found")
defer PidCCerrLock.RUnlock()
        }

}

###########################################
2- delete key map with delete option
###########################################
PidCCerrLock.Lock()
delete(PidCCerr, PID);
PidCCerrLock.UnLock()

###############################################
3- Write or re-write the last new key map with new value
###############################################
PidCCerrLock.Lock()
PidCCerr[PID] = CCerr
log.Println(“New map:”, PidCCerr)
defer PidCCerrLock.Unlock()

shoudl be work as this way?, can you calrify this please…?..thanks , I’ll apreciated a lot your help

I would suggest looking into another solution that doesn’t require as much locking - perhaps separate it out into goroutines and use channels to communicate between them. Mutexes shouldn’t be the first thing to reach for in Go. That said, if you do want to use locks, the patterns you are looking for are mostly, one:

func someFunc() {
    someMutex.Lock()
    defer someMutex.Unlock()

    // the rest of the function.
}

where the entire function is covered by the lock, and the defer ensures that it’s released when the function returns. The usefulness of the defer is that you can return from the function anywhere without worrying about the lock. Or, two:

func someFunc() {
    // code code code

    someMutex.Lock()
    // something that requires locking, such as map operations
    someMutex.Unlock()

    // the rest of the function.
}

No defer here, as you are only covering a tiny section of the code with the lock. Keep the section inside the lock small and clear so that it’s obvious when and how the lock is released.

1 Like

Ok Jakob
if I understood , for example I have this …
########################################

func ReadAndCheckKeyValue(KeyValue string) {
 someMutex.Lock()
    defer someMutex.Unlock()

    KeyValue, ok := some[key]
    if ok {
    log.Println("*********************** " )
    log.Println("value = " ,KeyValue)
	log.Println("PID " ,PIDOld )
    log.Println("*********************** " )

        } else {
                log.Println("key not found")
        }

}

func DeleteKeyValue(KeyValue string) {
 someMutex.Lock()
    defer someMutex.Unlock()

    delete(some, key)

}

func WriteKeyValue(KeyValueNew string) {
 someMutex.Lock()
    defer someMutex.Unlock()
    some[key] = KeyValueNew

}
var (
    some = make(map[string]string)
    someMutex = &sync.RWMutex{}

)

func main() {
//look at the find words by map key
KeyValue:= '10'

//read first if exists KeyValue in map key

ReadAndCheckKeyValue(KeyValue)

//delete if found it

DeleteKeyValue(KeyValue)

// Write with new Key

KeyValueNew := '11'
WriteKeyValue(KeyValueNew)    
}

it should be work?, thanks again, I’ll apreciated a lot!!

The locking looks like it ought to work. You have a number of other issues that will prevent the program from compiling, but the compiler will detail those for you. :slight_smile:

Note though that the defer call has a cost associated with it. Something like

func DeleteKeyValue(key string) {
    someMutex.Lock()
    defer someMutex.Unlock()
    delete(some, key)
}

would be better as

func DeleteKeyValue(key string) {
    someMutex.Lock()
    delete(some, key)
    someMutex.Unlock()
}

if you really want to wrap it in a function.

Great, yes!!! I made this code with not tested , it is just only for understood…
thanks again Jakob!!!

Hello Jakob
the code is improve, isn’t blocked qucly but a minute of running is blocked

this is my code modify for working with sync library

func CompareKeyValue(PIDOld string) {

        //Lock map Key
        PidCCerrLock.Lock()
    	//Extract Value from Map[key] , if value exists??
        CCerr, ok := PidCCerr[PIDOld]
        if ok {
        log.Println("*********************** " )
        log.Println("Ccerr Old " ,CCerr )
		log.Println("PID " ,PIDOld )
        log.Println("*********************** " )
        //log.Println("Pid New: ", CCerrNew)
                //fmt.Println("Substract: ", int (CCerrNew - value)
        } else {
                log.Println("key not found")
        }
        
        //Unlock map Key
        PidCCerrLock.Unlock()

}


                log.Println("############################################")
                log.Println("Begin PID 1")
                log.Println("Number i = ",i)
                SplitLine := strings.Split(SplitData[i],"|")
                Split := SplitLine[0]
                
                PID,Scrambled,CCerr := GetHeaderTS(Split,8,16)
               
                CompareKeyValue(PID) 

                //Lock map Key
                //PidCCerrLock.Lock()
                //log.Println("Old map:", PidCCerr)
                //Unlock map Key
                //PidCCerrLock.Unlock()
                
                //Lock map Key
                PidCCerrLock.Lock()
                PidCCerr[PID] = CCerr
                PidCCerrLock.Unlock()
                
                PidCCerrLock.Lock()
                log.Println("New map:", PidCCerr)
                PidCCerrLock.Unlock()

                //Lock map Key
                PidCCerrLock.Lock()
                delete(PidCCerr, PID);
                //Unlock map Key
                PidCCerrLock.Unlock()               

                //Header := Split[8:16]
                //PidCCerrLock.RUnlock()
                log.Println("Pid 1 data Hexa ",PID)
                log.Println("is Scrambled?? ",Scrambled)
                log.Println("CCerr => ",CCerr)

but is crashed… and this is the I’ve running with race option

2017/07/18 03:07:52 Begin PID 2
2017/07/18 03:07:52 New map: map[0101:9]
fatal error: concurrent map iteration and map write

goroutine 3253 [running]:
runtime.throw(0x111f9b, 0x26)
/usr/local/go/src/runtime/panic.go:596 +0x70 fp=0x111ee6bc sp=0x111ee6b0
runtime.mapiternext(0x120228a0)
/usr/local/go/src/runtime/hashmap.go:737 +0x6cc fp=0x111ee708 sp=0x111ee6bc
runtime.mapiterinit(0xf43a8, 0x104703e0, 0x120228a0)
/usr/local/go/src/runtime/hashmap.go:727 +0x2a4 fp=0x111ee734 sp=0x111ee708
reflect.mapiterinit(0xf43a8, 0x104703e0, 0x15)
/usr/local/go/src/runtime/hashmap.go:1150 +0x3c fp=0x111ee748 sp=0x111ee734
reflect.Value.MapKeys(0xf43a8, 0x104703e0, 0x15, 0x98, 0x76, 0x1)
/usr/local/go/src/reflect/value.go:1086 +0x90 fp=0x111ee79c sp=0x111ee748
fmt.(*pp).printValue(0x1040a280, 0xf43a8, 0x104703e0, 0x15, 0x76, 0x0)
/usr/local/go/src/fmt/print.go:741 +0xba8 fp=0x111ee894 sp=0x111ee79c
fmt.(*pp).printArg(0x1040a280, 0xf43a8, 0x104703e0, 0x76)
/usr/local/go/src/fmt/print.go:682 +0x1c4 fp=0x111ee8d4 sp=0x111ee894
fmt.(*pp).doPrintln(0x1040a280, 0x111eef94, 0x2, 0x2)
/usr/local/go/src/fmt/print.go:1138 +0x8c fp=0x111ee910 sp=0x111ee8d4
fmt.Sprintln(0x111eef94, 0x2, 0x2, 0x120ca6a8, 0x111eed7c)
/usr/local/go/src/fmt/print.go:264 +0x3c fp=0x111ee938 sp=0x111ee910
log.Println(0x111eef94, 0x2, 0x2)
/usr/local/go/src/log/log.go:297 +0x2c fp=0x111ee954 sp=0x111ee938
main.decodeData(0x118bc480, 0x1991)
/home/telsur/script/go/multicast.go:226 +0x9c8 fp=0x111eefe4 sp=0x111ee954
runtime.goexit()
/usr/local/go/src/runtime/asm_arm.s:1017 +0x4 fp=0x111eefe4 sp=0x111eefe4
created by main.msgHandler
/home/telsur/script/go/multicast.go:85 +0xec

goroutine 1 [runnable]:
sync.runtime_SemacquireMutex(0x1046a094)
/usr/local/go/src/runtime/sema.go:62 +0x24
sync.(*Mutex).Lock(0x1046a090)
/usr/local/go/src/sync/mutex.go:87 +0xd0
log.(*Logger).Output(0x1046a090, 0x2, 0x11d97500, 0x2a, 0x0, 0x0)
/usr/local/go/src/log/log.go:149 +0x50
log.Println(0x10535f2c, 0x3, 0x3)

maybe for socket programing, lock and unlock map key is too slow…please help me to find a solution…
thanks for all!!!

Chis…
I follow the lock and unlock ways that Jakob teach me and it’s improve but also still is crashed , I’ve share my code with you , and also I’ve run the program with race flag for your help please…
thanks for your help and have a good nigth…

package main

import (
	"encoding/hex"
    //"encoding/binary"
	"log"
	"net"
	"time"
    "strconv"
    "strings"
    //"bytes"
    "fmt"
    "sync"
)

const (
	srvAddr         = "239.255.5.79:2001"
	maxDatagramSize = 8192
    
)
//declare default PidCCerr for get CCerr

var (
    PidCCerr  = make(map[string]string)
    PidCCerrLock     = &sync.RWMutex{}
    PidCCerrSequence int
)

// New pids value
var PidNew = map[string]string{}
var start = time.Now()
//Split Words for extract Header
var f int
var l int

func main() {

	
    //go ping(srvAddr)
	serveMulticastUDP(srvAddr, msgHandler)
    
}

func ping(a string) {
	addr, err := net.ResolveUDPAddr("udp", a)
	if err != nil {
		log.Fatal(err)
	}
	c, err := net.DialUDP("udp", nil, addr)
	for {
		c.Write([]byte("hello, world\n"))
		time.Sleep(1 * time.Second)
	}
}

func serveMulticastUDP(a string, h func(*net.UDPAddr, int, []byte)) {
    
	addr, err := net.ResolveUDPAddr("udp", a)
	if err != nil {
		log.Fatal(err)
	}
	l, err := net.ListenMulticastUDP("udp", nil, addr)
	l.SetReadBuffer(maxDatagramSize)
	for {
		b := make([]byte, maxDatagramSize)
		n, src, err := l.ReadFromUDP(b)
		if err != nil {
			log.Fatal("ReadFromUDP failed:", err)
		}
		h(src, n, b)
	}
}

func msgHandler(src *net.UDPAddr, n int, b []byte) {
	log.Println(n, "bytes read from", src)
	//log.Println(hex.Dump(b[:n]))
    //Cut first 10 strigs
    //log.Println(hex.Dump(b[0:10:n]))
    //Data := int64(b)
    //log.Println(strconv.FormatInt(Data, 2))
    AllData := hex.Dump(b[:n])
    //log.Println(Data)
    //go decodeData (AllData)
    
    go decodeData(AllData)
}

func HexToBinary(s string) string {
    res := ""
    for _, c := range s {
        res = fmt.Sprintf("%s%.8b", res, c)
    }
    return res
}

func bin2int(binStr string) int {

      // base 2 for binary
      result, _ := strconv.ParseInt(binStr, 2, 64)
      return int(result)
}

func hex2int(hexStr string) int {
      // base 16 for hexadecimal
      result, _ := strconv.ParseInt(hexStr, 16, 64)
      return int(result)
}
 
func GetHeaderTS(SplitLine string , f int , l int) (string , string , string) {
        ///Split data 
        //SplitLines := strings.Split(SplitLine[i],"|")
        //Split := SplitLines[0]
       
        //log.Println("This is Header ",SplitLine)
        //log.Println("This is First ",f)
        //log.Println("This is Last ",l)
        Header := SplitLine[f:l]
        //log.Println("This is Header ",Header)
        PID := Header[2:6]
        CCerr := Header[len(Header) - 1:]
        //log.Println("CCerr ??   ",CCerr)
        Scrambled := Header[len(Header) - 2:len(Header)-1]
        //log.Println("Scrambled ??   ",Scrambled)        
        //Convert to decimal
        
        //PIDdecimal  := hex2int(PID)
        return PID,Scrambled,CCerr
} 

func CompareKeyValue(PIDOld string) {

        //Lock map Key
        PidCCerrLock.Lock()
    	//Extract Value from Map[key] , if value exists??
        CCerr, ok := PidCCerr[PIDOld]
        if ok {
        log.Println("*********************** " )
        log.Println("Ccerr Old " ,CCerr )
		log.Println("PID " ,PIDOld )
        log.Println("*********************** " )
        //log.Println("Pid New: ", CCerrNew)
                //fmt.Println("Substract: ", int (CCerrNew - value)
        } else {
                log.Println("key not found")
        }
        
        //Unlock map Key
        PidCCerrLock.Unlock()

}

func decodeData(dataParse string) {
    
    
    log.Println("Raw data")
    TS:=len(dataParse)
    log.Println("TS Length")
    log.Println(TS)
    if TS > 4000 {
        DataTS:=strings.Replace(dataParse, " ", "", -1)
        SplitData := strings.Split(DataTS,"\n")
        
        for i := 0; i < len(dataParse) ; {

            switch i {
            case 0:        
            
                log.Println("############################################")
                log.Println("############################################")
                log.Println("Begin PID 1")
                log.Println("Number i = ",i)
                SplitLine := strings.Split(SplitData[i],"|")
                Split := SplitLine[0]
                
                PID,Scrambled,CCerr := GetHeaderTS(Split,8,16)
               
                CompareKeyValue(PID) 

                //Lock map Key
                //PidCCerrLock.Lock()
                //log.Println("Old map:", PidCCerr)
                //Unlock map Key
                //PidCCerrLock.Unlock()
                
                //Lock map Key
                PidCCerrLock.Lock()
                PidCCerr[PID] = CCerr
                PidCCerrLock.Unlock()
                
                PidCCerrLock.Lock()
                log.Println("New map:", PidCCerr)
                PidCCerrLock.Unlock()

                //Lock map Key
                PidCCerrLock.Lock()
                delete(PidCCerr, PID);
                //Unlock map Key
                PidCCerrLock.Unlock()               

                //Header := Split[8:16]
                //PidCCerrLock.RUnlock()
                log.Println("Pid 1 data Hexa ",PID)
                log.Println("is Scrambled?? ",Scrambled)
                log.Println("CCerr => ",CCerr)
                
                //x := strconv.ParseUint(Header, 16, 32)
                //ParseUint(rawHex, 16, 32)
                //PID := Header[2:6]
                //log.Println("Pid Hexa   ",PID)
                //PIDdec  := hex2int(PID)
                
                //log.Println("Pid Number   ",PIDdec)
                //x := HexToBinary(Header)               
                //log.Println("Convert to Dec ",x)

                
                i+=11
                log.Println("END ")
            case 11:
                //log.Println("Number i = ",i)

                

                log.Println("############################################")
                log.Println("Begin PID 2 ")
                log.Println("map:", PidCCerr)
                SplitLine := strings.Split(SplitData[i],"|")
                Split := SplitLine[0]
                //PID,Scrambled,CCerr := GetHeaderTS(Split,len(Split) - 8,)
                //log.Println("Pid 1 data Hexa ",PID)
                //log.Println("is Scrambled?? ",Scrambled)
                //log.Println("CCerr => ",CCerr)
                
                f = len(Split) - 8
                l = f + 8
                //Header := Split[f:]
                PID,Scrambled,CCerr := GetHeaderTS(Split,f,l)
               
                
                CompareKeyValue(PID) 

                //Lock map Key
                //PidCCerrLock.Lock()
                //log.Println("Old map:", PidCCerr)
                //Unlock map Key
                //PidCCerrLock.Unlock()
                
                //Lock map Key
                PidCCerrLock.Lock()
                PidCCerr[PID] = CCerr
                PidCCerrLock.Unlock()
                
                PidCCerrLock.Lock()
                log.Println("New map:", PidCCerr)
                PidCCerrLock.Unlock()

                //Lock map Key
                PidCCerrLock.Lock()
                delete(PidCCerr, PID);
                //Unlock map Key
                PidCCerrLock.Unlock()               

                //Header := Split[8:16]
                //PidCCerrLock.RUnlock()
                log.Println("Pid 2 data Hexa ",PID)
                log.Println("is Scrambled?? ",Scrambled)
                log.Println("CCerr => ",CCerr)
                
                
               // Header := Split[f:l]
               // log.Println("Header => ",Header)  
                
                i+=12
                log.Println("END ")
                log.Println("############################################")
            case 23:
                log.Println("Begin PID 3 ")
                //log.Println("Number i = ",i)
                SplitLine := strings.Split(SplitData[i],"|")
                Split := SplitLine[0]
                
                f = len(Split) - 16
                l = f + 8
                
                PID,Scrambled,CCerr := GetHeaderTS(Split,f,l)
                
                CompareKeyValue(PID) 

                //Lock map Key
                //PidCCerrLock.Lock()
                //log.Println("Old map:", PidCCerr)
                //Unlock map Key
                //PidCCerrLock.Unlock()
                
                //Lock map Key
                PidCCerrLock.Lock()
                PidCCerr[PID] = CCerr
                PidCCerrLock.Unlock()
                
                PidCCerrLock.Lock()
                log.Println("New map:", PidCCerr)
                PidCCerrLock.Unlock()

                //Lock map Key
                PidCCerrLock.Lock()
                delete(PidCCerr, PID);
                //Unlock map Key
                PidCCerrLock.Unlock()             

                //Header := Split[8:16]
                //PidCCerrLock.RUnlock()
                log.Println("Pid 3 data Hexa ",PID)
                log.Println("is Scrambled?? ",Scrambled)
                log.Println("CCerr => ",CCerr)
                 
                //Header := Split[f:l]
                //log.Println("Header => ",Header)  
                
                i+=12
                log.Println("END ")
                log.Println("############################################")
            case 35:
                log.Println("Begin PID 4 ")
                //log.Println("Number i = ",i)
                SplitLine := strings.Split(SplitData[i],"|")
                Split := SplitLine[0]
                f = len(Split) - 24
                l = f + 8
                
                PID,Scrambled,CCerr := GetHeaderTS(Split,f,l)
                
                CompareKeyValue(PID) 

                //Lock map Key
                //PidCCerrLock.Lock()
                //log.Println("Old map:", PidCCerr)
                //Unlock map Key
                //PidCCerrLock.Unlock()
                
                //Lock map Key
                PidCCerrLock.Lock()
                PidCCerr[PID] = CCerr
                PidCCerrLock.Unlock()
                
                PidCCerrLock.Lock()
                log.Println("New map:", PidCCerr)
                PidCCerrLock.Unlock()

                //Lock map Key
                PidCCerrLock.Lock()
                delete(PidCCerr, PID);
                //Unlock map Key
                PidCCerrLock.Unlock()                

                //Header := Split[8:16]
                //PidCCerrLock.RUnlock()
                log.Println("Pid 4 data Hexa ",PID)
                log.Println("is Scrambled?? ",Scrambled)
                log.Println("CCerr => ",CCerr)
                
                //Header := Split[f:l]
                //log.Println("Header => ",Header)  
                
                //Header := Split[8:16]
                
                i+=12
                log.Println("END ")
            case 47:
                log.Println("############################################")
                log.Println("Begin ")
                log.Println("Number i = ",i)
                SplitLine := strings.Split(SplitData[i],"|")
                Split := SplitLine[0]

                f = 8
                l = f + 8
                
                PID,Scrambled,CCerr := GetHeaderTS(Split,f,l)
                CompareKeyValue(PID) 

                //Lock map Key
                //PidCCerrLock.Lock()
                //log.Println("Old map:", PidCCerr)
                //Unlock map Key
                //PidCCerrLock.Unlock()
                
                //Lock map Key
                PidCCerrLock.Lock()
                PidCCerr[PID] = CCerr
                PidCCerrLock.Unlock()
                
                PidCCerrLock.Lock()
                log.Println("New map:", PidCCerr)
                PidCCerrLock.Unlock()

                //Lock map Key
                PidCCerrLock.Lock()
                delete(PidCCerr, PID);
                //Unlock map Key
                PidCCerrLock.Unlock()                

                //Header := Split[8:16]
                //PidCCerrLock.RUnlock()
                log.Println("Pid 5 data Hexa ",PID)
                log.Println("is Scrambled?? ",Scrambled)
                log.Println("CCerr => ",CCerr)    
                
                //Header := Split[f:l]
                //log.Println("Header => ",Header)         
                i+=11   
                log.Println("END ")
            case 58:
                log.Println("############################################")
                log.Println("Begin ")
                SplitLine := strings.Split(SplitData[i],"|")
                Split := SplitLine[0]
                
                f = len(Split) - 8
                l = f + 8
                
                PID,Scrambled,CCerr := GetHeaderTS(Split,f,l)
                
                CompareKeyValue(PID) 

                //Lock map Key
                //PidCCerrLock.Lock()
                //log.Println("Old map:", PidCCerr)
                //Unlock map Key
                //PidCCerrLock.Unlock()
                
                //Lock map Key
                PidCCerrLock.Lock()
                PidCCerr[PID] = CCerr
                PidCCerrLock.Unlock()
                
                PidCCerrLock.Lock()
                log.Println("New map:", PidCCerr)
                PidCCerrLock.Unlock()

                //Lock map Key
                PidCCerrLock.Lock()
                delete(PidCCerr, PID);
                //Unlock map Key
                PidCCerrLock.Unlock()                

                //Header := Split[8:16]
                //PidCCerrLock.RUnlock()
                log.Println("Pid 6 data Hexa ",PID)
                log.Println("is Scrambled?? ",Scrambled)
                log.Println("CCerr => ",CCerr)  
                
                
                
                //Header := Split[f:l]
                //log.Println("Header => ",Header)         
                i+=12
                log.Println("END ")
            case 70:
                log.Println("############################################")
                log.Println("Begin ")
                SplitLine := strings.Split(SplitData[i],"|")
                Split := SplitLine[0]
                f = 24
                l = f + 8
                
                PID,Scrambled,CCerr := GetHeaderTS(Split,f,l)
                
                
                CompareKeyValue(PID) 

                //Lock map Key
                //PidCCerrLock.Lock()
                //log.Println("Old map:", PidCCerr)
                //Unlock map Key
                //PidCCerrLock.Unlock()
                
                //Lock map Key
                PidCCerrLock.Lock()
                PidCCerr[PID] = CCerr
                PidCCerrLock.Unlock()
                
                PidCCerrLock.Lock()
                log.Println("New map:", PidCCerr)
                PidCCerrLock.Unlock()

                //Lock map Key
                PidCCerrLock.Lock()
                delete(PidCCerr, PID);
                //Unlock map Key
                PidCCerrLock.Unlock()                

                //Header := Split[8:16]
                //PidCCerrLock.RUnlock()
                log.Println("Pid 7 data Hexa ",PID)
                log.Println("is Scrambled?? ",Scrambled)
                log.Println("CCerr => ",CCerr)   
                
                
                //Header := Split[f:l]
                //log.Println("Pid 6 data",Header)      
                i+=1
                log.Println("END ")
            }
            
            //log.Println("Number i = ",i)
            //SplitLine := strings.Split(SplitData[i],"|")
            //log.Println(SplitLine[0])
            

            if i > 70  {
                elapsed := time.Since(start)
                log.Printf("Multicast  took %s", elapsed)
        
                break
            }
            
    //i +=1
        }
        log.Println("#########################################")
     } 
    
    

    

}

thanks!!!

and this is the race log where is crashed my code…I’ll apreciatedd your help and also Jakob help

2017/07/18 03:07:52 CCerr =>  1
2017/07/18 03:07:52 END 
2017/07/18 03:07:52 ############################################
2017/07/18 03:07:52 Begin 
2017/07/18 03:07:52 key not found
2017/07/18 03:07:52 New map: map[0100:7]
2017/07/18 03:07:52 Pid 5 data Hexa  0100
2017/07/18 03:07:52 is Scrambled??  1
2017/07/18 03:07:52 CCerr =>  7
2017/07/18 03:07:52 END 
2017/07/18 03:07:52 ############################################
2017/07/18 03:07:52 Begin 
2017/07/18 03:07:52 key not found
2017/07/18 03:07:52 Raw data
2017/07/18 03:07:52 TS Length
2017/07/18 03:07:52 6545
2017/07/18 03:07:52 1316 bytes read from 192.168.44.134:49152
2017/07/18 03:07:52 New map: map[0100:5]
2017/07/18 03:07:52 Pid 1 data Hexa  0100
2017/07/18 03:07:52 is Scrambled??  1
2017/07/18 03:07:52 CCerr =>  5
2017/07/18 03:07:52 END 
2017/07/18 03:07:52 ############################################
2017/07/18 03:07:52 Begin PID 2 
2017/07/18 03:07:52 map: map[]
2017/07/18 03:07:52 key not found
2017/07/18 03:07:52 New map: map[0100:a]
2017/07/18 03:07:52 Pid 3 data Hexa  0100
2017/07/18 03:07:52 is Scrambled??  1
2017/07/18 03:07:52 CCerr =>  a
2017/07/18 03:07:52 Raw data
2017/07/18 03:07:52 TS Length
2017/07/18 03:07:52 6545
2017/07/18 03:07:52 END 
2017/07/18 03:07:52 ############################################
2017/07/18 03:07:52 Begin PID 4 
2017/07/18 03:07:52 key not found
2017/07/18 03:07:52 1316 bytes read from 192.168.44.134:49152
2017/07/18 03:07:52 New map: map[0100:9]
2017/07/18 03:07:52 Pid 1 data Hexa  0100
2017/07/18 03:07:52 is Scrambled??  1
2017/07/18 03:07:52 CCerr =>  9
2017/07/18 03:07:52 END 
2017/07/18 03:07:52 ############################################
2017/07/18 03:07:52 Begin PID 2 
2017/07/18 03:07:52 map: map[]
2017/07/18 03:07:52 1316 bytes read from 192.168.44.134:49152
2017/07/18 03:07:52 ############################################
2017/07/18 03:07:52 ############################################
2017/07/18 03:07:52 Begin PID 1
2017/07/18 03:07:52 Number i =  0
2017/07/18 03:07:52 key not found
2017/07/18 03:07:52 New map: map[0100:0]
2017/07/18 03:07:52 Raw data
2017/07/18 03:07:52 TS Length
2017/07/18 03:07:52 6545
2017/07/18 03:07:52 ############################################
2017/07/18 03:07:52 ############################################
2017/07/18 03:07:52 Begin PID 1
2017/07/18 03:07:52 Number i =  0
2017/07/18 03:07:52 Pid 4 data Hexa  0100
2017/07/18 03:07:52 is Scrambled??  1
2017/07/18 03:07:52 CCerr =>  0
2017/07/18 03:07:52 END 
2017/07/18 03:07:52 ############################################
2017/07/18 03:07:52 Begin 
2017/07/18 03:07:52 Number i =  47
2017/07/18 03:07:52 key not found
2017/07/18 03:07:52 New map: map[0100:f]
2017/07/18 03:07:52 Pid 4 data Hexa  0100
2017/07/18 03:07:52 is Scrambled??  1
2017/07/18 03:07:52 CCerr =>  f
2017/07/18 03:07:52 END 
2017/07/18 03:07:52 ############################################
2017/07/18 03:07:52 Begin 
2017/07/18 03:07:52 Number i =  47
2017/07/18 03:07:52 key not found
2017/07/18 03:07:52 New map: map[0100:5]
2017/07/18 03:07:52 Pid 7 data Hexa  0100
2017/07/18 03:07:52 ############################################
2017/07/18 03:07:52 ############################################
2017/07/18 03:07:52 Begin PID 1
2017/07/18 03:07:52 Number i =  0
2017/07/18 03:07:52 is Scrambled??  1
2017/07/18 03:07:52 CCerr =>  5
2017/07/18 03:07:52 END 
2017/07/18 03:07:52 Multicast  took 13.46637787s
2017/07/18 03:07:52 #########################################
2017/07/18 03:07:52 key not found
2017/07/18 03:07:52 New map: map[0100:a]
2017/07/18 03:07:52 Pid 3 data Hexa  0100
2017/07/18 03:07:52 is Scrambled??  1
2017/07/18 03:07:52 CCerr =>  a
2017/07/18 03:07:52 END 
2017/07/18 03:07:52 ############################################
2017/07/18 03:07:52 Begin PID 4 
2017/07/18 03:07:52 key not found
2017/07/18 03:07:52 New map: map[0100:6]
2017/07/18 03:07:52 Pid 1 data Hexa  0100
2017/07/18 03:07:52 is Scrambled??  1
2017/07/18 03:07:52 CCerr =>  6
2017/07/18 03:07:52 key not found
2017/07/18 03:07:52 New map: map[0100:6]
2017/07/18 03:07:52 Pid 4 data Hexa  0100
2017/07/18 03:07:52 is Scrambled??  1
2017/07/18 03:07:52 CCerr =>  6
2017/07/18 03:07:52 END 
2017/07/18 03:07:52 ############################################
2017/07/18 03:07:52 Begin 
2017/07/18 03:07:52 Number i =  47
2017/07/18 03:07:52 key not found
2017/07/18 03:07:52 END 
2017/07/18 03:07:52 ############################################
2017/07/18 03:07:52 Begin PID 2 
2017/07/18 03:07:52 New map: map[0101:9]
fatal error: concurrent map iteration and map write

goroutine 3253 [running]:
runtime.throw(0x111f9b, 0x26)
        /usr/local/go/src/runtime/panic.go:596 +0x70 fp=0x111ee6bc sp=0x111ee6b0
runtime.mapiternext(0x120228a0)
        /usr/local/go/src/runtime/hashmap.go:737 +0x6cc fp=0x111ee708 sp=0x111ee6bc
runtime.mapiterinit(0xf43a8, 0x104703e0, 0x120228a0)
        /usr/local/go/src/runtime/hashmap.go:727 +0x2a4 fp=0x111ee734 sp=0x111ee708
reflect.mapiterinit(0xf43a8, 0x104703e0, 0x15)
        /usr/local/go/src/runtime/hashmap.go:1150 +0x3c fp=0x111ee748 sp=0x111ee734
reflect.Value.MapKeys(0xf43a8, 0x104703e0, 0x15, 0x98, 0x76, 0x1)
        /usr/local/go/src/reflect/value.go:1086 +0x90 fp=0x111ee79c sp=0x111ee748
fmt.(*pp).printValue(0x1040a280, 0xf43a8, 0x104703e0, 0x15, 0x76, 0x0)
        /usr/local/go/src/fmt/print.go:741 +0xba8 fp=0x111ee894 sp=0x111ee79c
fmt.(*pp).printArg(0x1040a280, 0xf43a8, 0x104703e0, 0x76)
        /usr/local/go/src/fmt/print.go:682 +0x1c4 fp=0x111ee8d4 sp=0x111ee894
fmt.(*pp).doPrintln(0x1040a280, 0x111eef94, 0x2, 0x2)
        /usr/local/go/src/fmt/print.go:1138 +0x8c fp=0x111ee910 sp=0x111ee8d4
fmt.Sprintln(0x111eef94, 0x2, 0x2, 0x120ca6a8, 0x111eed7c)
        /usr/local/go/src/fmt/print.go:264 +0x3c fp=0x111ee938 sp=0x111ee910
log.Println(0x111eef94, 0x2, 0x2)
        /usr/local/go/src/log/log.go:297 +0x2c fp=0x111ee954 sp=0x111ee938
main.decodeData(0x118bc480, 0x1991)
        /home/telsur/script/go/multicast.go:226 +0x9c8 fp=0x111eefe4 sp=0x111ee954
runtime.goexit()
        /usr/local/go/src/runtime/asm_arm.s:1017 +0x4 fp=0x111eefe4 sp=0x111eefe4
created by main.msgHandler
        /home/telsur/script/go/multicast.go:85 +0xec

goroutine 1 [runnable]:
sync.runtime_SemacquireMutex(0x1046a094)
        /usr/local/go/src/runtime/sema.go:62 +0x24
sync.(*Mutex).Lock(0x1046a090)
        /usr/local/go/src/sync/mutex.go:87 +0xd0
log.(*Logger).Output(0x1046a090, 0x2, 0x11d97500, 0x2a, 0x0, 0x0)
        /usr/local/go/src/log/log.go:149 +0x50
log.Println(0x10535f2c, 0x3, 0x3)
        /usr/local/go/src/log/log.go:297 +0x54
main.msgHandler(0x11eb3a00, 0x524, 0x10568000, 0x2000, 0x2000)
        /home/telsur/script/go/multicast.go:75 +0xa4
main.serveMulticastUDP(0x10ddd3, 0x11, 0x1139f0)
        /home/telsur/script/go/multicast.go:70 +0x1d4
main.main()
        /home/telsur/script/go/multicast.go:40 +0x2c

goroutine 17 [syscall, locked to thread]:
runtime.goexit()
        /usr/local/go/src/runtime/asm_arm.s:1017 +0x4

goroutine 3388 [semacquire]:
sync.runtime_SemacquireMutex(0x19deb4)
        /usr/local/go/src/runtime/sema.go:62 +0x24
sync.(*Mutex).Lock(0x19deb0)
        /usr/local/go/src/sync/mutex.go:87 +0xd0
sync.(*RWMutex).Lock(0x19deb0)
        /usr/local/go/src/sync/rwmutex.go:86 +0x20
main.CompareKeyValue(0x11cf390a, 0x4)
        /home/telsur/script/go/multicast.go:133 +0x24
main.decodeData(0x1178a480, 0x1991)
        /home/telsur/script/go/multicast.go:177 +0x10e8
created by main.msgHandler
        /home/telsur/script/go/multicast.go:85 +0xec

goroutine 2994 [semacquire]:
sync.runtime_SemacquireMutex(0x19deb4)
        /usr/local/go/src/runtime/sema.go:62 +0x24
sync.(*Mutex).Lock(0x19deb0)
        /usr/local/go/src/sync/mutex.go:87 +0xd0
sync.(*RWMutex).Lock(0x19deb0)
        /usr/local/go/src/sync/rwmutex.go:86 +0x20
main.CompareKeyValue(0x1129d5aa, 0x4)
        /home/telsur/script/go/multicast.go:133 +0x24
main.decodeData(0x112c2480, 0x1991)
        /home/telsur/script/go/multicast.go:240 +0xac0
created by main.msgHandler
        /home/telsur/script/go/multicast.go:85 +0xec

goroutine 3372 [semacquire]:
sync.runtime_SemacquireMutex(0x19deb4)
        /usr/local/go/src/runtime/sema.go:62 +0x24
sync.(*Mutex).Lock(0x19deb0)
        /usr/local/go/src/sync/mutex.go:87 +0xd0
sync.(*RWMutex).Lock(0x19deb0)
        /usr/local/go/src/sync/rwmutex.go:86 +0x20
main.CompareKeyValue(0x1139000a, 0x4)
        /home/telsur/script/go/multicast.go:133 +0x24
main.decodeData(0x11972480, 0x1991)
        /home/telsur/script/go/multicast.go:177 +0x10e8
created by main.msgHandler
        /home/telsur/script/go/multicast.go:85 +0xec

goroutine 2223 [semacquire]:
sync.runtime_SemacquireMutex(0x19deb4)
        /usr/local/go/src/runtime/sema.go:62 +0x24
sync.(*Mutex).Lock(0x19deb0)
        /usr/local/go/src/sync/mutex.go:87 +0xd0
sync.(*RWMutex).Lock(0x19deb0)
        /usr/local/go/src/sync/rwmutex.go:86 +0x20
main.CompareKeyValue(0x109da3db, 0x4)
        /home/telsur/script/go/multicast.go:133 +0x24
main.decodeData(0x10960480, 0x1991)
        /home/telsur/script/go/multicast.go:379 +0x1754
created by main.msgHandler
        /home/telsur/script/go/multicast.go:85 +0xec

goroutine 2398 [semacquire]:
sync.runtime_SemacquireMutex(0x19deb4)
        /usr/local/go/src/runtime/sema.go:62 +0x24
sync.(*Mutex).Lock(0x19deb0)
        /usr/local/go/src/sync/mutex.go:87 +0xd0
sync.(*RWMutex).Lock(0x19deb0)
        /usr/local/go/src/sync/rwmutex.go:86 +0x20
main.CompareKeyValue(0x10dccd74, 0x4)
        /home/telsur/script/go/multicast.go:133 +0x24
main.decodeData(0x10e3b500, 0x1991)
        /home/telsur/script/go/multicast.go:423 +0x2798
created by main.msgHandler
        /home/telsur/script/go/multicast.go:85 +0xec

goroutine 2463 [semacquire]:
sync.runtime_SemacquireMutex(0x19deb4)
        /usr/local/go/src/runtime/sema.go:62 +0x24
sync.(*Mutex).Lock(0x19deb0)
        /usr/local/go/src/sync/mutex.go:87 +0xd0
sync.(*RWMutex).Lock(0x19deb0)
        /usr/local/go/src/sync/rwmutex.go:86 +0x20
main.CompareKeyValue(0x116776db, 0x4)
        /home/telsur/script/go/multicast.go:133 +0x24
main.decodeData(0x1115ef80, 0x1991)
        /home/telsur/script/go/multicast.go:379 +0x1754
created by main.msgHandler
        /home/telsur/script/go/multicast.go:85 +0xec

goroutine 2448 [semacquire]:
sync.runtime_SemacquireMutex(0x19deb4)
        /usr/local/go/src/runtime/sema.go:62 +0x24
sync.(*Mutex).Lock(0x19deb0)
        /usr/local/go/src/sync/mutex.go:87 +0xd0
sync.(*RWMutex).Lock(0x19deb0)
        /usr/local/go/src/sync/rwmutex.go:86 +0x20
main.CompareKeyValue(0x11384120, 0x4)
        /home/telsur/script/go/multicast.go:133 +0x24
main.decodeData(0x111ada80, 0x1991)
        /home/telsur/script/go/multicast.go:332 +0x1c70
created by main.msgHandler
        /home/telsur/script/go/multicast.go:85 +0xec

goroutine 2866 [semacquire]:
sync.runtime_SemacquireMutex(0x19deb4)
        /usr/local/go/src/runtime/sema.go:62 +0x24
sync.(*Mutex).Lock(0x19deb0)
        /usr/local/go/src/sync/mutex.go:87 +0xd0
sync.(*RWMutex).Lock(0x19deb0)
        /usr/local/go/src/sync/rwmutex.go:86 +0x20
main.CompareKeyValue(0x11a24b66, 0x4)
        /home/telsur/script/go/multicast.go:133 +0x24
main.decodeData(0x11997500, 0x1991)
        /home/telsur/script/go/multicast.go:287 +0x418
created by main.msgHandler
        /home/telsur/script/go/multicast.go:85 +0xec

goroutine 2768 [semacquire]:
sync.runtime_SemacquireMutex(0x19deb4)
        /usr/local/go/src/runtime/sema.go:62 +0x24
sync.(*Mutex).Lock(0x19deb0)
        /usr/local/go/src/sync/mutex.go:87 +0xd0
sync.(*RWMutex).Lock(0x19deb0)
        /usr/local/go/src/sync/rwmutex.go:86 +0x20
main.CompareKeyValue(0x1154c2ab, 0x4)
        /home/telsur/script/go/multicast.go:133 +0x24
main.decodeData(0x1175f500, 0x1991)
        /home/telsur/script/go/multicast.go:240 +0xac0
created by main.msgHandler
        /home/telsur/script/go/multicast.go:85 +0xec

goroutine 2563 [semacquire]:
sync.runtime_SemacquireMutex(0x19deb4)
        /usr/local/go/src/runtime/sema.go:62 +0x24
sync.(*Mutex).Lock(0x19deb0)
        /usr/local/go/src/sync/mutex.go:87 +0xd0
sync.(*RWMutex).Lock(0x19deb0)
        /usr/local/go/src/sync/rwmutex.go:86 +0x20
main.CompareKeyValue(0x10c35ba9, 0x4)
        /home/telsur/script/go/multicast.go:133 +0x24
main.decodeData(0x10dfc480, 0x1991)
        /home/telsur/script/go/multicast.go:240 +0xac0
created by main.msgHandler
        /home/telsur/script/go/multicast.go:85 +0xec

goroutine 2434 [semacquire]:
sync.runtime_SemacquireMutex(0x19deb4)
        /usr/local/go/src/runtime/sema.go:62 +0x24
sync.(*Mutex).Lock(0x19deb0)
        /usr/local/go/src/sync/mutex.go:87 +0xd0
sync.(*RWMutex).Lock(0x19deb0)
        /usr/local/go/src/sync/rwmutex.go:86 +0x20
main.CompareKeyValue(0x107e4e1e, 0x4)
        /home/telsur/script/go/multicast.go:133 +0x24
main.decodeData(0x109e1500, 0x1991)
        /home/telsur/script/go/multicast.go:332 +0x1c70
created by main.msgHandler
        /home/telsur/script/go/multicast.go:85 +0xec

goroutine 3525 [semacquire]:
sync.runtime_SemacquireMutex(0x19deb4)
        /usr/local/go/src/runtime/sema.go:62 +0x24
sync.(*Mutex).Lock(0x19deb0)
        /usr/local/go/src/sync/mutex.go:87 +0xd0
sync.(*RWMutex).Lock(0x19deb0)
        /usr/local/go/src/sync/rwmutex.go:86 +0x20
main.CompareKeyValue(0x11cf130a, 0x4)
        /home/telsur/script/go/multicast.go:133 +0x24
main.decodeData(0x1115a000, 0x1991)
        /home/telsur/script/go/multicast.go:177 +0x10e8
created by main.msgHandler
        /home/telsur/script/go/multicast.go:85 +0xec

goroutine 2796 [semacquire]:
sync.runtime_SemacquireMutex(0x19deb4)
        /usr/local/go/src/runtime/sema.go:62 +0x24
sync.(*Mutex).Lock(0x19deb0)
        /usr/local/go/src/sync/mutex.go:87 +0xd0
sync.(*RWMutex).Lock(0x19deb0)
        /usr/local/go/src/sync/rwmutex.go:86 +0x20
main.CompareKeyValue(0x11a23865, 0x4)
        /home/telsur/script/go/multicast.go:133 +0x24
main.decodeData(0x119d3500, 0x1991)
        /home/telsur/script/go/multicast.go:287 +0x418
created by main.msgHandler
        /home/telsur/script/go/multicast.go:85 +0xec

goroutine 2608 [semacquire]:
sync.runtime_SemacquireMutex(0x19deb4)
        /usr/local/go/src/runtime/sema.go:62 +0x24
sync.(*Mutex).Lock(0x19deb0)
        /usr/local/go/src/sync/mutex.go:87 +0xd0
sync.(*RWMutex).Lock(0x19deb0)
        /usr/local/go/src/sync/rwmutex.go:86 +0x20
main.CompareKeyValue(0x10d4b6dc, 0x4)
        /home/telsur/script/go/multicast.go:133 +0x24
main.decodeData(0x10e27500, 0x1991)
        /home/telsur/script/go/multicast.go:379 +0x1754
created by main.msgHandler
        /home/telsur/script/go/multicast.go:85 +0xec

goroutine 3027 [semacquire]:
sync.runtime_SemacquireMutex(0x19deb4)
        /usr/local/go/src/runtime/sema.go:62 +0x24
sync.(*Mutex).Lock(0x19deb0)
        /usr/local/go/src/sync/mutex.go:87 +0xd0
sync.(*RWMutex).Lock(0x19deb0)
        /usr/local/go/src/sync/rwmutex.go:86 +0x20
main.CompareKeyValue(0x11ad130a, 0x4)
        /home/telsur/script/go/multicast.go:133 +0x24
main.decodeData(0x118f0000, 0x1991)
        /home/telsur/script/go/multicast.go:177 +0x10e8
created by main.msgHandler
        /home/telsur/script/go/multicast.go:85 +0xec

goroutine 2926 [semacquire]:
sync.runtime_SemacquireMutex(0x19deb4)
        /usr/local/go/src/runtime/sema.go:62 +0x24
sync.(*Mutex).Lock(0x19deb0)
        /usr/local/go/src/sync/mutex.go:87 +0xd0
sync.(*RWMutex).Lock(0x19deb0)
        /usr/local/go/src/sync/rwmutex.go:86 +0x20
main.CompareKeyValue(0x1057200a, 0x4)
        /home/telsur/script/go/multicast.go:133 +0x24
main.decodeData(0x10a56480, 0x1991)
        /home/telsur/script/go/multicast.go:177 +0x10e8
created by main.msgHandler
        /home/telsur/script/go/multicast.go:85 +0xec

goroutine 3282 [semacquire]:
sync.runtime_SemacquireMutex(0x19deb4)
        /usr/local/go/src/runtime/sema.go:62 +0x24
sync.(*Mutex).Lock(0x19deb0)
        /usr/local/go/src/sync/mutex.go:87 +0xd0
sync.(*RWMutex).Lock(0x19deb0)
        /usr/local/go/src/sync/rwmutex.go:86 +0x20
main.CompareKeyValue(0x11cf4c0a, 0x4)
        /home/telsur/script/go/multicast.go:133 +0x24
main.decodeData(0x11d3fa80, 0x1991)
        /home/telsur/script/go/multicast.go:177 +0x10e8
created by main.msgHandler
        /home/telsur/script/go/multicast.go:85 +0xec

goroutine 2915 [semacquire]:
sync.runtime_SemacquireMutex(0x19deb4)
        /usr/local/go/src/runtime/sema.go:62 +0x24
sync.(*Mutex).Lock(0x19deb0)
        /usr/local/go/src/sync/mutex.go:87 +0xd0
sync.(*RWMutex).Lock(0x19deb0)
        /usr/local/go/src/sync/rwmutex.go:86 +0x20
main.CompareKeyValue(0x10abb90a, 0x4)
        /home/telsur/script/go/multicast.go:133 +0x24
main.decodeData(0x1068ea00, 0x1991)
        /home/telsur/script/go/multicast.go:177 +0x10e8
created by main.msgHandler
        /home/telsur/script/go/multicast.go:85 +0xec

goroutine 3406 [semacquire]:
sync.runtime_SemacquireMutex(0x19deb4)
        /usr/local/go/src/runtime/sema.go:62 +0x24
sync.(*Mutex).Lock(0x19deb0)
        /usr/local/go/src/sync/mutex.go:87 +0xd0
sync.(*RWMutex).Lock(0x19deb0)
        /usr/local/go/src/sync/rwmutex.go:86 +0x20
main.CompareKeyValue(0x11c3e60a, 0x4)
        /home/telsur/script/go/multicast.go:133 +0x24
main.decodeData(0x11d80f80, 0x1991)
        /home/telsur/script/go/multicast.go:177 +0x10e8
created by main.msgHandler
        /home/telsur/script/go/multicast.go:85 +0xec

goroutine 2614 [semacquire]:
sync.runtime_SemacquireMutex(0x19deb4)
        /usr/local/go/src/runtime/sema.go:62 +0x24
sync.(*Mutex).Lock(0x19deb0)
        /usr/local/go/src/sync/mutex.go:87 +0xd0
sync.(*RWMutex).Lock(0x19deb0)
        /usr/local/go/src/sync/rwmutex.go:86 +0x20
main.CompareKeyValue(0x111748aa, 0x4)
        /home/telsur/script/go/multicast.go:133 +0x24
main.decodeData(0x10ee8f80, 0x1991)
        /home/telsur/script/go/multicast.go:240 +0xac0
created by main.msgHandler
        /home/telsur/script/go/multicast.go:85 +0xec

goroutine 2090 [semacquire]:
sync.runtime_SemacquireMutex(0x19deb4)
        /usr/local/go/src/runtime/sema.go:62 +0x24
sync.(*Mutex).Lock(0x19deb0)
        /usr/local/go/src/sync/mutex.go:87 +0xd0
sync.(*RWMutex).Lock(0x19deb0)
        /usr/local/go/src/sync/rwmutex.go:86 +0x20
main.CompareKeyValue(0x10627039, 0x4)
        /home/telsur/script/go/multicast.go:133 +0x24
main.decodeData(0x10950480, 0x1991)
        /home/telsur/script/go/multicast.go:469 +0x222c
created by main.msgHandler
        /home/telsur/script/go/multicast.go:85 +0xec

goroutine 1802 [semacquire]:
sync.runtime_SemacquireMutex(0x19deb4)
        /usr/local/go/src/runtime/sema.go:62 +0x24
sync.(*Mutex).Lock(0x19deb0)
        /usr/local/go/src/sync/mutex.go:87 +0xd0
sync.(*RWMutex).Lock(0x19deb0)
        /usr/local/go/src/sync/rwmutex.go:86 +0x20
main.CompareKeyValue(0x10641c38, 0x4)
        /home/telsur/script/go/multicast.go:133 +0x24
main.decodeData(0x109f3500, 0x1991)
        /home/telsur/script/go/multicast.go:469 +0x222c
created by main.msgHandler
        /home/telsur/script/go/multicast.go:85 +0xec

goroutine 2645 [semacquire]:
sync.runtime_SemacquireMutex(0x19deb4)
        /usr/local/go/src/runtime/sema.go:62 +0x24
sync.(*Mutex).Lock(0x19deb0)
        /usr/local/go/src/sync/mutex.go:87 +0xd0
sync.(*RWMutex).Lock(0x19deb0)
        /usr/local/go/src/sync/rwmutex.go:86 +0x20
main.CompareKeyValue(0x10d07dd4, 0x4)
        /home/telsur/script/go/multicast.go:133 +0x24
main.decodeData(0x1109a000, 0x1991)
        /home/telsur/script/go/multicast.go:379 +0x1754
created by main.msgHandler
        /home/telsur/script/go/multicast.go:85 +0xec

goroutine 3061 [semacquire]:
sync.runtime_SemacquireMutex(0x19deb4)
        /usr/local/go/src/runtime/sema.go:62 +0x24
sync.(*Mutex).Lock(0x19deb0)
        /usr/local/go/src/sync/mutex.go:87 +0xd0
sync.(*RWMutex).Lock(0x19deb0)
        /usr/local/go/src/sync/rwmutex.go:86 +0x20
main.CompareKeyValue(0x11bacd7d, 0x4)
        /home/telsur/script/go/multicast.go:133 +0x24
main.decodeData(0x11b75500, 0x1991)
        /home/telsur/script/go/multicast.go:423 +0x2798
created by main.msgHandler
        /home/telsur/script/go/multicast.go:85 +0xec

goroutine 3379 [semacquire]:
sync.runtime_SemacquireMutex(0x19deb4)
        /usr/local/go/src/runtime/sema.go:62 +0x24
sync.(*Mutex).Lock(0x19deb0)
        /usr/local/go/src/sync/mutex.go:87 +0xd0
sync.(*RWMutex).Lock(0x19deb0)
        /usr/local/go/src/sync/rwmutex.go:86 +0x20
main.CompareKeyValue(0x10a34c0a, 0x4)
        /home/telsur/script/go/multicast.go:133 +0x24
main.decodeData(0x10d3c480, 0x1991)
        /home/telsur/script/go/multicast.go:177 +0x10e8
created by main.msgHandler
        /home/telsur/script/go/multicast.go:85 +0xec

goroutine 2471 [semacquire]:
sync.runtime_SemacquireMutex(0x19deb4)
        /usr/local/go/src/runtime/sema.go:62 +0x24
sync.(*Mutex).Lock(0x19deb0)
        /usr/local/go/src/sync/mutex.go:87 +0xd0
sync.(*RWMutex).Lock(0x19deb0)
        /usr/local/go/src/sync/rwmutex.go:86 +0x20
main.CompareKeyValue(0x11710938, 0x4)
        /home/telsur/script/go/multicast.go:133 +0x24
main.decodeData(0x116b7500, 0x1991)
        /home/telsur/script/go/multicast.go:469 +0x222c
created by main.msgHandler
        /home/telsur/script/go/multicast.go:85 +0xec

goroutine 2799 [semacquire]:
sync.runtime_SemacquireMutex(0x19deb4)
        /usr/local/go/src/runtime/sema.go:62 +0x24
sync.(*Mutex).Lock(0x19deb0)
        /usr/local/go/src/sync/mutex.go:87 +0xd0
sync.(*RWMutex).Lock(0x19deb0)
        /usr/local/go/src/sync/rwmutex.go:86 +0x20
main.CompareKeyValue(0x118a16d9, 0x4)
        /home/telsur/script/go/multicast.go:133 +0x24
main.decodeData(0x1146da80, 0x1991)
        /home/telsur/script/go/multicast.go:379 +0x1754
created by main.msgHandler
        /home/telsur/script/go/multicast.go:85 +0xec

goroutine 2334 [semacquire]:
sync.runtime_SemacquireMutex(0x19deb4)
        /usr/local/go/src/runtime/sema.go:62 +0x24
sync.(*Mutex).Lock(0x19deb0)
        /usr/local/go/src/sync/mutex.go:87 +0xd0
sync.(*RWMutex).Lock(0x19deb0)
        /usr/local/go/src/sync/rwmutex.go:86 +0x20
main.CompareKeyValue(0x108f081e, 0x4)
        /home/telsur/script/go/multicast.go:133 +0x24
main.decodeData(0x10f6ea00, 0x1991)
        /home/telsur/script/go/multicast.go:332 +0x1c70
created by main.msgHandler
        /home/telsur/script/go/multicast.go:85 +0xec

goroutine 2869 [semacquire]:
sync.runtime_SemacquireMutex(0x19deb4)
        /usr/local/go/src/runtime/sema.go:62 +0x24
sync.(*Mutex).Lock(0x19deb0)
        /usr/local/go/src/sync/mutex.go:87 +0xd0
sync.(*RWMutex).Lock(0x19deb0)
        /usr/local/go/src/sync/rwmutex.go:86 +0x20
main.CompareKeyValue(0x110b30dd, 0x4)
        /home/telsur/script/go/multicast.go:133 +0x24
main.decodeData(0x10fa1a80, 0x1991)
        /home/telsur/script/go/multicast.go:379 +0x1754
created by main.msgHandler
        /home/telsur/script/go/multicast.go:85 +0xec

goroutine 3352 [semacquire]:
sync.runtime_SemacquireMutex(0x19deb4)
        /usr/local/go/src/runtime/sema.go:62 +0x24
sync.(*Mutex).Lock(0x19deb0)
        /usr/local/go/src/sync/mutex.go:87 +0xd0
sync.(*RWMutex).Lock(0x19deb0)
        /usr/local/go/src/sync/rwmutex.go:86 +0x20
main.CompareKeyValue(0x10eaac0a, 0x4)
        /home/telsur/script/go/multicast.go:133 +0x24
main.decodeData(0x11287a80, 0x1991)
        /home/telsur/script/go/multicast.go:177 +0x10e8
created by main.msgHandler
        /home/telsur/script/go/multicast.go:85 +0xec

goroutine 2839 [semacquire]:
sync.runtime_SemacquireMutex(0x19deb4)
        /usr/local/go/src/runtime/sema.go:62 +0x24
sync.(*Mutex).Lock(0x19deb0)
        /usr/local/go/src/sync/mutex.go:87 +0xd0
sync.(*RWMutex).Lock(0x19deb0)
        /usr/local/go/src/sync/rwmutex.go:86 +0x20
main.CompareKeyValue(0x119188a7, 0x4)
        /home/telsur/script/go/multicast.go:133 +0x24
main.decodeData(0x115b4f80, 0x1991)
        /home/telsur/script/go/multicast.go:240 +0xac0
created by main.msgHandler
        /home/telsur/script/go/multicast.go:85 +0xec

goroutine 3277 [semacquire]:
sync.runtime_SemacquireMutex(0x19deb4)
        /usr/local/go/src/runtime/sema.go:62 +0x24
sync.(*Mutex).Lock(0x19deb0)
        /usr/local/go/src/sync/mutex.go:87 +0xd0
sync.(*RWMutex).Lock(0x19deb0)
        /usr/local/go/src/sync/rwmutex.go:86 +0x20
main.CompareKeyValue(0x10b9260a, 0x4)
        /home/telsur/script/go/multicast.go:133 +0x24
main.decodeData(0x1070ca00, 0x1991)
        /home/telsur/script/go/multicast.go:177 +0x10e8
created by main.msgHandler
        /home/telsur/script/go/multicast.go:85 +0xec

goroutine 3109 [semacquire]:
sync.runtime_SemacquireMutex(0x19deb4)
        /usr/local/go/src/runtime/sema.go:62 +0x24
sync.(*Mutex).Lock(0x19deb0)
        /usr/local/go/src/sync/mutex.go:87 +0xd0
sync.(*RWMutex).Lock(0x19deb0)
        /usr/local/go/src/sync/rwmutex.go:86 +0x20
main.CompareKeyValue(0x10b10eab, 0x4)
        /home/telsur/script/go/multicast.go:133 +0x24
main.decodeData(0x108ba480, 0x1991)
        /home/telsur/script/go/multicast.go:240 +0xac0
created by main.msgHandler
        /home/telsur/script/go/multicast.go:85 +0xec

goroutine 2900 [semacquire]:
sync.runtime_SemacquireMutex(0x19deb4)
        /usr/local/go/src/runtime/sema.go:62 +0x24
sync.(*Mutex).Lock(0x19deb0)
        /usr/local/go/src/sync/mutex.go:87 +0xd0
sync.(*RWMutex).Lock(0x19deb0)
        /usr/local/go/src/sync/rwmutex.go:86 +0x20
main.CompareKeyValue(0x11328e20, 0x4)
        /home/telsur/script/go/multicast.go:133 +0x24
main.decodeData(0x1112da80, 0x1991)
        /home/telsur/script/go/multicast.go:332 +0x1c70
created by main.msgHandler
        /home/telsur/script/go/multicast.go:85 +0xec

goroutine 2277 [semacquire]:
sync.runtime_SemacquireMutex(0x19deb4)
        /usr/local/go/src/runtime/sema.go:62 +0x24
sync.(*Mutex).Lock(0x19deb0)
        /usr/local/go/src/sync/mutex.go:87 +0xd0
sync.(*RWMutex).Lock(0x19deb0)
        /usr/local/go/src/sync/rwmutex.go:86 +0x20
main.CompareKeyValue(0x1051937b, 0x4)
        /home/telsur/script/go/multicast.go:133 +0x24
main.decodeData(0x10a5b500, 0x1991)
        /home/telsur/script/go/multicast.go:423 +0x2798
created by main.msgHandler
        /home/telsur/script/go/multicast.go:85 +0xec

Jakob…
thanks again for your helpo, I’ve post all code below if you what to put an eye…
thanks again for all!!!

Looks like the read came from one of the many lines like log.Println("map:", PidCCerr).

Because there are so many accesses to PidCCerr, it is really difficult to figure out which ones aren’t locked properly. I would wrap PidCCerr's map in a struct and write accessors that do whatever needs to be done (including the locking). This will both cleanup your code by removing the locking noise, and ensure the correct locks happen.

To handle the logging lines, implement fmt.Stringer for the type, doing the locking in that function.

1 Like

Wow, that’s still quite some code. 500+ lines is maybe a bit too big for this forum.

When I try to run the code I get a panic. After inserting a missing error handling after l, err := net.ListenMulticastUDP("udp", nil, addr) I get a setsockopt error, and troubleshooting that would take too much time, sorry.

Looking at the output that you posted, the first stack trace points to line 226 in multicast.go, which is a comment (//log.Println("Pid 1 data Hexa ",PID)). I pasted your code verbatim into my editor, but the line numbering might still be a bit off for some reason.

Anyway, a few lines above there is a print statement that reads PidCCerr outside any locked region:

log.Println("map:", PidCCerr)

As @nathankerr already pointed out, these unguarded read accesses to PidCCerr are a likely cause for the error. You will want to consider @nathankerr’s suggestion of establishing a thread-safe struct around PidCCerr with accessor methods that handle locking and unlocking internally, so that any part of your code that accesses the map enters a locked region automatically by calling one of the accessor methods.

The second stack trace points to line 75 (log.Println(n, "bytes read from", src)) that looks unrelated as it does not access any of the maps.

All other stack traces point to line 133, which is a Lock() operation:

func CompareKeyValue(PIDOld string) {

	//Lock map Key
	PidCCerrLock.Lock()    // <- line 133

This means that a lot of goroutines are waiting to get write access to PidCCerr, and this is the situation that @calmh warned about. If an unlock is missing or happens too late (for example, due to deferring it to the very end of the function), you might eventually arrive at a deadlock situation.

The suggested guarded access through accessor methods should also cover this case.

1 Like

Thaks for your help Nathan, I’ll clean it and I’ll try again…
I’ll let you know asap.

1 Like

Thanks for your help Chris…
yes ,is a sniffer, then try to Join to multicast stream, that is the reason that you have a problem with this…and also, I’ve read your post and I understand all, but
this line…

###############################################################################
This means that a lot of goroutines are waiting to get write access to PidCCerr, and this is the situation that @calmh warned about. If an unlock is missing or happens too late (for example, due to deferring it to the very end of the function), you might eventually arrive at a deadlock situation.
#################################################################################

your suggest that access like this way…

Instendet of this
#####################################

            CompareKeyValue(PID) 

            //Lock map Key
            //PidCCerrLock.Lock()
            //log.Println("Old map:", PidCCerr)
            //Unlock map Key
            //PidCCerrLock.Unlock()
            
            //Lock map Key
            PidCCerrLock.Lock()
            PidCCerr[PID] = CCerr
            PidCCerrLock.Unlock()

#######################################
put my code like this

    //Lock map Key
    PidCCerrLock.Lock()
	//Extract Value from Map[key] , if value exists??
    CCerr, ok := PidCCerr[PIDOld]
    if ok {
    log.Println("*********************** " )
    log.Println("Ccerr Old " ,CCerr )
	log.Println("PID " ,PIDOld )
    log.Println("*********************** " )
    //log.Println("Pid New: ", CCerrNew)
            //fmt.Println("Substract: ", int (CCerrNew - value)
    } else {
            log.Println("key not found")
    }
    
    //Unlock map Key
    PidCCerrLock.Unlock()

            //Lock map Key
            PidCCerrLock.Lock()
            PidCCerr[PID] = CCerr
            PidCCerrLock.Unlock()

???, without any goroutine?.that mean directly on the switch statement?..thanks for your help!!!

Lots of this will be mitigated when the PidCCerr is only accessed through accessor functions, as those functions won’t do any extra work like logging.

Nathan, Thanks again for your help , I’ll apreciated a lot, I’m very new in “Go”, that is the reason for be sure that I understood all, you mean that :
1- not logged not necessary map key values, right?
2 - access to map key by functions not from fixed access.

############################################
this use a function

CompareKeyValue(PID)

func CompareKeyValue(PIDOld string) {

    //Lock map Key
    PidCCerrLock.Lock()
    CCerr, ok := PidCCerr[PIDOld]
    if ok {
    log.Println("*********************** " )
    log.Println("Ccerr Old " ,CCerr )
	log.Println("PID " ,PIDOld )
    log.Println("*********************** " )
    //log.Println("Pid New: ", CCerrNew)
            //fmt.Println("Substract: ", int (CCerrNew - value)
    } else {
            log.Println("key not found")
    }
    
    //Unlock map Key
    PidCCerrLock.Unlock()

}

############################################
Instead of this??, fixed way
############################################

            //Lock map Key
            PidCCerrLock.Lock()
            delete(PidCCerr, PID);
            //Unlock map Key
            PidCCerrLock.Unlock()

For CompareKeyValue, you get a lock at the beginning of the function and release it at the end.

The lock is only needed for CCerr, ok := PidCCerr[PIDOld], but it is held while all the log.Printlns execute.

If you had a function like (pseudocode):

func (p *PidCCerr) Get(pid) (ccerr, bool) {
    lock()
    defer unlock()

    return p.pidccerr[pid]
}

The lock can’t accidentally be held while the log.Printlns run.

EDIT:

In case it wasn’t clear, you would call PidCCerr.Get(PIDOld) instead of PidCCerr[PIDOld].

1 Like