How to resolve access conflicts on shared resources?

WBOY
Release: 2024-02-09 22:03:08
forward
1092 people have browsed it

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)
    }
}
Copy after login

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()

 }
Copy after login

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!

Related labels:
source:stackoverflow.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!