Maison  >  Article  >  développement back-end  >  Comment résoudre les conflits d’accès sur les ressources partagées ?

Comment résoudre les conflits d’accès sur les ressources partagées ?

WBOY
WBOYavant
2024-02-09 22:03:081093parcourir

Comment résoudre les conflits d’accès sur les ressources partagées ?

l'éditeur php Strawberry vous présentera comment résoudre le problème de conflit d'accès aux ressources partagées. Dans la programmation multithread ou multiprocessus, lorsque plusieurs threads ou processus accèdent à des ressources partagées en même temps, des incohérences de données ou des résultats erronés peuvent en résulter. Afin de résoudre ce problème, des mécanismes de synchronisation tels que les verrous mutex, les sémaphores et les variables de condition peuvent être utilisés pour garantir un accès mutuellement exclusif aux ressources. En utilisant rationnellement ces mécanismes de synchronisation, nous pouvons résoudre efficacement le problème des conflits d'accès aux ressources partagées et garantir l'exactitude et la stabilité du programme.

Contenu des questions

Il existe un service de test avec 2 requêtes. Est-il suffisant d'utiliser actualorders 变量形式的共享资源。假设正在运行数百个并行查询,则 actualorders 变量中可能会发生数据冲突。特别是当我循环遍历数组时。为了防止这种情况,使用 mutex pour ces requêtes, comme je le fais dans l'exemple ci-dessous ?

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 de contournement

L'utilisation d'un mutex comme vous l'avez fait empêche les courses de données. Cependant, votre implémentation peut être améliorée.

Vous pouvez utiliser une variable rwmutex,对 getorders 函数使用读锁,对 createorder 函数使用锁。这将允许在写入时对 actualorders pour un accès exclusif mais autoriser les lectures partagées :

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

 }

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer