phpエディタStrawberryでは、共有リソースのアクセス競合問題を解決する方法を紹介します。マルチスレッドまたはマルチプロセスプログラミングでは、複数のスレッドまたはプロセスが共有リソースに同時にアクセスすると、データの不整合や誤った結果が発生する可能性があります。この問題を解決するには、ミューテックス ロック、セマフォ、条件変数などの同期メカニズムを使用して、リソースへの相互排他的アクセスを確保します。これらの同期メカニズムを合理的に使用することで、共有リソースのアクセス競合の問題を効果的に解決し、プログラムの正確性と安定性を確保できます。
リクエストが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 変数への排他的アクセスが許可されますが、共有読み取りは許可されます:
リーリー
以上が共有リソースでのアクセス競合を解決するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。