Rumah > Artikel > pembangunan bahagian belakang > 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.
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) } }
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!