>  기사  >  백엔드 개발  >  공유 리소스에 대한 액세스 충돌을 해결하는 방법은 무엇입니까?

공유 리소스에 대한 액세스 충돌을 해결하는 방법은 무엇입니까?

WBOY
WBOY앞으로
2024-02-09 22:03:081092검색

공유 리소스에 대한 액세스 충돌을 해결하는 방법은 무엇입니까?

php editor 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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 stackoverflow.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제