Heim >Backend-Entwicklung >Golang >Wie können Zugriffskonflikte auf gemeinsam genutzte Ressourcen gelöst werden?

Wie können Zugriffskonflikte auf gemeinsam genutzte Ressourcen gelöst werden?

WBOY
WBOYnach vorne
2024-02-09 22:03:081160Durchsuche

Wie können Zugriffskonflikte auf gemeinsam genutzte Ressourcen gelöst werden?

Der PHP-Editor Strawberry stellt Ihnen vor, wie Sie das Zugriffskonfliktproblem gemeinsam genutzter Ressourcen lösen können. Wenn bei der Multithread- oder Multiprozessprogrammierung mehrere Threads oder Prozesse gleichzeitig auf gemeinsam genutzte Ressourcen zugreifen, kann es zu Dateninkonsistenzen oder fehlerhaften Ergebnissen kommen. Um dieses Problem zu lösen, können Synchronisationsmechanismen wie Mutexe, Semaphore und Bedingungsvariablen verwendet werden, um einen sich gegenseitig ausschließenden Zugriff auf Ressourcen sicherzustellen. Durch den rationalen Einsatz dieser Synchronisationsmechanismen können wir das Problem von Zugriffskonflikten gemeinsam genutzter Ressourcen effektiv lösen und die Korrektheit und Stabilität des Programms sicherstellen.

Frageninhalt

Es gibt einen Testdienst mit 2 Anfragen. Reicht es aus, actualorders 变量形式的共享资源。假设正在运行数百个并行查询,则 actualorders 变量中可能会发生数据冲突。特别是当我循环遍历数组时。为了防止这种情况,使用 mutex für diese Anfragen zu verwenden, wie ich es im Beispiel unten tue?

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

Workaround

Die Verwendung eines Mutex, wie Sie es getan haben, verhindert Datenrennen. Ihre Implementierung kann jedoch verbessert werden.

Sie können eine rwmutex,对 getorders 函数使用读锁,对 createorder 函数使用锁。这将允许在写入时对 actualorders-Variable für den exklusiven Zugriff verwenden, aber gemeinsame Lesevorgänge zulassen:

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

 }

Das obige ist der detaillierte Inhalt vonWie können Zugriffskonflikte auf gemeinsam genutzte Ressourcen gelöst werden?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen