2016-10-19 2 views
0

다음은 데이터에 안전하게 액세스하기 위해 뮤텍스 잠금을 사용하는 방법의 예입니다. 내 질문은 뮤텍스 잠금 및 잠금 해제 대신 CSP (통신 순차 프로세스)를 사용하여 동일한 작업을 수행하는 방법은 무엇입니까? 당신이 실제로 이동 채널을 구현하는 방법을 본다면채널을 안전하게 사용하여 골란에서 데이터를 동기화하는 방법

type Stack struct { 
    top *Element 
    size int 
    sync.Mutex 
} 

func (ss *Stack) Len() int { 
    ss.Lock() 
    size := ss.size 
    ss.Unlock() 
    return size 

} 

func (ss *Stack) Push(value interface{}) { 
    ss.Lock() 
    ss.top = &Element{value, ss.top} 
    ss.size++ 
    ss.Unlock() 
} 

func (ss *SafeStack) Pop() (value interface{}) { 
    ss.Lock() 
    size := ss.size 
    ss.Unlock() 
    if size > 0 { 
    ss.Lock() 
    value, ss.top = ss.top.value, ss.top.next 
    ss.size-- 
    ss.Unlock() 
    return 
    } 

    return nil 
} 
+0

숙제 문제입니까? 'Element'의 정의를 포함하여 코드가 누락 된 것 같습니다. –

+2

왜? 뮤텍스는이 경우에 사용할 올바른 기본 요소입니까? (또한, 그것은 훨씬 더 깨끗하고 에러를 덜 일으키는'defer'를 사용합니다. – JimB

+1

채널 패러다임의 모든 목적은 뮤텍스를 제거하는 것입니다. 채널을 사용하면 채널없이 동기화 할 수 있습니다. 그러나 당신에게 보여주기 위해서, 우리는 당신의 실제 코드를 필요로 할 것입니다. 단지 잠금 코드가 아닙니다. 일반적으로 채널을 효과적으로 사용하려면 프로그램 아키텍처를 설계해야합니다. 효과적으로 사용하기 위해 몇 줄을 바꿀 수는 없습니다. – sinned

답변

1

, 당신은 값이 통과 될 때까지 실행을 차단 처리 추가적인 스레드와 배열 주위에 뮤텍스를 참조 본질적 것입니다. 채널의 일은 한 자리에서 다른 곳으로 데이터를 쉽게 옮기는 것입니다. 당신이 잠금 및 잠금 해제가 어디 따라서이 예를 들어 같은 일이있을 것이다 :

func example() { 
    resChan := make(int chan) 
    go func(){ 
     resChan <- 1 
    }() 
    go func(){ 
     res := <-resChan 
    } 
} 

그래서 예에서 첫 번째 goroutine 두 번째 goroutine 채널에서 읽을 때까지 값을 전송 한 후 차단됩니다.

Go와 뮤텍스에서 이렇게하려면 sync.WaitGroup을 사용하여 값을 설정할 때 그룹에 하나를 추가 한 다음 그룹에서 그룹을 해제하면 두 번째 goroutine이 값을 잠그고 잠금을 해제합니다.

당신의 예제에있는 괴짜들은 골로드가 1 개가 아니기 때문에 하나의 메인 goroutine에서 모두 발생하며 잠금 장치는 전통적으로 (예 : c thread처럼) 사용되어 채널이 실제로 아무 것도 성취하지 못합니다. 네가 가지고있는 예는 반 패턴으로 간주 될 것입니다. 골란의 속담처럼 "기억을 공유하고 의사 소통을 통해 메모리를 공유함으로써 의사 소통을하지 마십시오."라고 말합니다.

관련 문제