Home >Backend Development >Golang >How to resolve access conflicts on shared resources?

How to resolve access conflicts on shared resources?

WBOY
WBOYforward
2024-02-09 22:03:081158browse

How to resolve access conflicts on shared resources?

php editor Strawberry will introduce you how to solve the access conflict problem of shared resources. In multi-threaded or multi-process programming, when multiple threads or processes access shared resources at the same time, data inconsistency or erroneous results may result. In order to solve this problem, synchronization mechanisms such as mutex locks, semaphores, and condition variables can be used to ensure mutually exclusive access to resources. By rationally using these synchronization mechanisms, we can effectively solve the problem of access conflicts of shared resources and ensure the correctness and stability of the program.

Question content

There is a test service with 2 requests. These requests use shared resources in the form of actualorders variables. Assuming hundreds of parallel queries are running, data conflicts may occur in the actualorders variable. Especially when I'm looping through the array. To prevent this, would it be enough to use mutex, like I do in the example below?

main.go

package main

import (
    "encoding/json"
    "errors"
    "fmt"
    "net/http"
    "os"
    "time"
)

type Order struct {
    Room      string    `json:"room"`
    UserEmail string    `json:"email"`
    From      time.Time `json:"from"`
    To        time.Time `json:"to"`
}

var ActualOrders = []Order{}

var mutex sync.Mutex

func getOrders(responseWriter http.ResponseWriter, request *http.Request) {
    userEmail := request.URL.Query().Get("email")

    results := []Order{}

    mutex.Lock()

    for _, item := range ActualOrders {
        if item.UserEmail == userEmail {
            results = append(results, item)
        }
    }

    mutex.Unlock()

    bytes, err := json.Marshal(results)
    if err != nil {
        http.Error(responseWriter, err.Error(), http.StatusInternalServerError)
        return
    }

    responseWriter.Header().Set("Content-type", "application/json")
    responseWriter.WriteHeader(http.StatusOK)
    responseWriter.Write(bytes)
}

func createOrder(responseWriter http.ResponseWriter, request *http.Request) {
    var newOrder Order

    requestBody := request.Body
    defer request.Body.Close()
    err := json.NewDecoder(requestBody).Decode(&newOrder)
    if err != nil {
        http.Error(responseWriter, err.Error(), http.StatusBadRequest)
        return
    }

    mutex.Lock()

    for _, order := range ActualOrders {
        if !(newOrder.To.Before(order.From) || newOrder.From.After(order.To)) {
            http.Error(responseWriter, http.StatusText(http.StatusConflict), http.StatusConflict)
            return
        }
    }

    ActualOrders = append(ActualOrders, newOrder)

    mutex.Unlock()

    responseWriter.WriteHeader(http.StatusCreated)
}

func main() {
    mux := http.NewServeMux()

    mux.HandleFunc("/orders", getOrders)
    mux.HandleFunc("/order", createOrder)

    err := http.ListenAndServe(":8080", mux)
    if errors.Is(err, http.ErrServerClosed) {
        fmt.Printf("server closed\n")
    } else if err != nil {
        fmt.Printf("error starting server: %s\n", err)
        os.Exit(1)
    }
}

Solution

Using a mutex like you did can prevent data races. However, your implementation can be improved.

You can use rwmutex to use read locks on the getorders function and locks on the createorder function. This will allow exclusive access to the actualorders variable when writing, but allow shared reading:

var mutex sync.RWMutex

func getOrders(responseWriter http.ResponseWriter, request *http.Request) {
    ...
    mutex.RLock()
    ... 
    mutex.RUnlock()
}

func createOrder(responseWriter http.ResponseWriter, request *http.Request) {
    ...
    mutex.Lock()
    for _, order := range ActualOrders {
       ... 
    }
    ActualOrders = append(ActualOrders, newOrder)
    mutex.Unlock()

 }

The above is the detailed content of How to resolve access conflicts on shared resources?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:stackoverflow.com. If there is any infringement, please contact admin@php.cn delete