Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Bagaimana untuk menyelesaikan konflik akses pada sumber yang dikongsi?

Bagaimana untuk menyelesaikan konflik akses pada sumber yang dikongsi?

WBOY
WBOYke hadapan
2024-02-09 22:03:081093semak imbas

Bagaimana untuk menyelesaikan konflik akses pada sumber yang dikongsi?

editor php Strawberry akan memperkenalkan anda cara menyelesaikan masalah konflik akses sumber yang dikongsi. Dalam pengaturcaraan berbilang benang atau berbilang proses, apabila berbilang rangkaian atau proses mengakses sumber yang dikongsi pada masa yang sama, ketidakkonsistenan data atau hasil yang salah mungkin berlaku. Untuk menyelesaikan masalah ini, mekanisme penyegerakan seperti mutex, semaphore, dan pembolehubah keadaan boleh digunakan untuk memastikan akses yang saling eksklusif kepada sumber. Dengan menggunakan mekanisme penyegerakan ini secara rasional, kami boleh menyelesaikan masalah konflik akses sumber yang dikongsi dengan berkesan dan memastikan ketepatan dan kestabilan program.

Kandungan soalan

Ada perkhidmatan ujian dengan 2 permintaan. Adakah cukup untuk menggunakan actualorders 变量形式的共享资源。假设正在运行数百个并行查询,则 actualorders 变量中可能会发生数据冲突。特别是当我循环遍历数组时。为了防止这种情况,使用 mutex untuk permintaan ini, seperti yang saya lakukan dalam contoh di bawah?

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

Penyelesaian

Menggunakan mutex seperti yang anda lakukan menghalang perlumbaan data. Walau bagaimanapun, pelaksanaan anda boleh dipertingkatkan.

Anda boleh menggunakan pembolehubah rwmutex,对 getorders 函数使用读锁,对 createorder 函数使用锁。这将允许在写入时对 actualorders untuk akses eksklusif tetapi benarkan bacaan dikongsi:

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

 }

Atas ialah kandungan terperinci Bagaimana untuk menyelesaikan konflik akses pada sumber yang dikongsi?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:stackoverflow.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam