简体   繁体   中英

Concurrently writing and reading from map causes potential race condition

I have a very basic Golang application that creates and runs a HTTP server. The server has 2 endpoints, one to send data and one to receive.

Upon each POST request to the server, parse the incoming data from the body and push it onto a channel. I then have a function that reads from the channel and saves the data to a map.

Upon each GET request to the server, JSON marshal the map and send it to the client.

Each request to the HTTP server runs asynchronously and the worker function writes to the map synchronously in its own goroutine.

Basic pseudo code is as follows:

package main

import (
    "net/http"
)

type dataStore map[string]string

func listenHandler(stream chan string) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        // JSON unmarshal request body

        // push data onto stream
        stream <- data
    }
}

func serveHandler(store *dataStore) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        // JSON marshal data store
        // serve to client
    }
}

func worker(stream <-chan string) *dataStore {
    store := make(dataStore)
    go func() {
        for data := range stream {
            // process and write data to map
        }
    }()
    return &store
}

func main() {
    stream := make(chan string)
    store := worker(stream)

    http.HandleFunc("/listen", listenHandler(stream))
    http.HandleFunc("/serve", serveHandler(store))

    http.ListenAndServe(":8080", nil)
}

I have tested and ran the application with no problems, however I have been told it has a potential race condition and I am not sure why. Is this true?

In the code given, you're only synchronizing your writes, not your reads; that means you still might read from the map while you're writing to it, which would be a race condition.

To make it thread-safe, you need to wrap both reads and writes in a concurrency structure - either using channels or a mutex - in order to ensure that only one thread is accessing it at any given time if it is a write operation. Multiple threads can safely read at the same time, as long as no thread is writing to it. RWMutex provides this functionality explicitly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM