php小編草莓將為您介紹如何解決共享資源的存取衝突問題。在多執行緒或多進程程式設計中,當多個執行緒或進程同時存取共享資源時,可能會導致資料不一致或錯誤的結果。為了解決這個問題,可以使用互斥鎖、訊號量、條件變數等同步機制來確保資源的互斥存取。透過合理使用這些同步機制,我們可以有效解決共享資源的存取衝突問題,確保程式的正確性和穩定性。
有一個測試服務有 2 個請求。這些請求使用 actualorders
變數形式的共享資源。假設正在執行數百個並行查詢,則 actualorders 變數中可能會發生資料衝突。特別是當我循環遍歷數組時。為了防止這種情況,使用 mutex
是否足夠,就像我在下面的範例中所做的那樣?
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) } }
像您一樣使用互斥鎖可以防止資料爭用。不過,您的實施還可以改進。
您可以使用 rwmutex
,對 getorders
函數使用讀鎖,對 createorder
函數使用鎖定。這將允許在寫入時對 actualorders
變數進行獨佔訪問,但允許共享讀取:
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() }
以上是如何解決共享資源的存取衝突問題?的詳細內容。更多資訊請關注PHP中文網其他相關文章!