Bagaimana untuk menyelesaikan konflik akses pada sumber yang dikongsi?

WBOY
Lepaskan: 2024-02-09 22:03:08
ke hadapan
1093 orang telah melayarinya

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)
    }
}
Salin selepas log masuk

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

 }
Salin selepas log masuk

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!

Label berkaitan:
sumber:stackoverflow.com
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!