l'éditeur php Strawberry vous présentera comment résoudre le problème de conflit d'accès aux ressources partagées. Dans la programmation multithread ou multiprocessus, lorsque plusieurs threads ou processus accèdent à des ressources partagées en même temps, des incohérences de données ou des résultats erronés peuvent en résulter. Afin de résoudre ce problème, des mécanismes de synchronisation tels que les verrous mutex, les sémaphores et les variables de condition peuvent être utilisés pour garantir un accès mutuellement exclusif aux ressources. En utilisant rationnellement ces mécanismes de synchronisation, nous pouvons résoudre efficacement le problème des conflits d'accès aux ressources partagées et garantir l'exactitude et la stabilité du programme.
Il existe un service de test avec 2 requêtes. Est-il suffisant d'utiliser actualorders
变量形式的共享资源。假设正在运行数百个并行查询,则 actualorders 变量中可能会发生数据冲突。特别是当我循环遍历数组时。为了防止这种情况,使用 mutex
pour ces requêtes, comme je le fais dans l'exemple ci-dessous ?
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) } }
L'utilisation d'un mutex comme vous l'avez fait empêche les courses de données. Cependant, votre implémentation peut être améliorée.
Vous pouvez utiliser une variable rwmutex
,对 getorders
函数使用读锁,对 createorder
函数使用锁。这将允许在写入时对 actualorders
pour un accès exclusif mais autoriser les lectures partagées :
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() }
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!