Mohsen
Mohsen

Reputation: 4266

Go maps fails the concurency test

When I run the following code:

import (
"log"
"sync"
"testing"
"time"
)
func TestConcurrency(t *testing.T) {
var mutex sync.RWMutex
dictionary := make(map[interface{}]interface{})
go func() {
    var value interface{}
    for {
        go func() {
            mutex.Lock()
            dictionary["Key"] = ""
            mutex.Unlock()
        }()

        go func() {
            mutex.RLock()
            value = dictionary["Key"]
            mutex.RUnlock()
        }()

    }
    log.Println(value)
}()
}

using :

go test -race fileName.go

It results in:

Found 1 data race(s)

How can I solve this?

I have many concurrent writes and reads.

Upvotes: 0

Views: 69

Answers (2)

David S
David S

Reputation: 19

This code will work correctly:

    go func() {
        mutex.Lock()
        value = dictionary["Key"]
        mutex.Unlock()
    }()

It protects the variable value from concurrent write.

Upvotes: 0

JimB
JimB

Reputation: 109331

If you look at the error presented by the race detector, you would see that it reported concurrent writes on the value = dictionary["Key"] line, meaning the race being detected is on value, not dictionary.

You are concurrently accessing 2 variables, dictionary and value. You can't use the read lock to protect reads on the map, and writes to the value variable. You either need a second mutex, or you need to always use mutex.Lock to serialize access to both variables.

Upvotes: 4

Related Questions