GoLang RW뮤텍스
이 튜토리얼은 GoLang에서 rwmutex
를 사용하는 방법을 보여줍니다.
GoLang RWMutex
뮤텍스
는 언제든지 어떤 스레드가 변수에 액세스했는지 추적하는 데 사용되는 상호 배제의 약자입니다. 뮤텍스는 GoLang의 sync
패키지에서 제공되는 데이터 구조입니다.
뮤텍스
는 Go 코드를 사용하여 동시성을 수행할 때 사용됩니다. 다음은 GoLang에서 뮤텍스
를 사용하는 간단한 예입니다.
package main
import (
"fmt"
"sync"
"time"
)
func EvenNumber(num int) bool {
return num%2 == 0
}
func main() {
num := 2
var DemoMutex sync.Mutex
go func() {
DemoMutex.Lock()
defer DemoMutex.Unlock()
EvenNum := EvenNumber(num)
time.Sleep(5 * time.Millisecond)
if EvenNum {
fmt.Println("The number", num, " is even")
return
}
fmt.Println("The number", num, "is odd")
}()
go func() {
DemoMutex.Lock()
num++
DemoMutex.Unlock()
}()
time.Sleep(time.Second)
}
위의 코드는 숫자가 짝수인지 홀수인지 확인합니다. 여기서 동시 고루틴
은 데이터를 손상시킬 수 있으므로 뮤텍스
를 사용하여 손상을 방지하기 위해 데이터를 잠그고 잠금 해제합니다.
출력을 참조하십시오.
The number 2 is even
mutex
와 RWmutex
는 다릅니다. 여기서 mutex
는 단순 뮤텍스이고 RWmutex
는 리더-라이터 상호 배제 잠금입니다. RWMutex
를 사용하면 임의의 수의 판독기 또는 한 명의 작성자가 잠금을 보유합니다.
RWMutex
의 값이 0이면 잠금 해제된 뮤텍스입니다. RWMutex
뮤텍스를 사용하여 동일한 예제를 시도해 봅시다.
package main
import (
"fmt"
"sync"
"time"
)
func EvenNumber(num int) bool {
return num%2 == 0
}
func main() {
num := 2
var DemoRWM sync.RWMutex
// both goroutines call DemoRWM.Lock() before accessing `num` and then call the DemoRWM.Unlock after they are done
go func() {
DemoRWM.RLock()
defer DemoRWM.RUnlock()
EvenNum := EvenNumber(num)
time.Sleep(5 * time.Millisecond)
if EvenNum {
fmt.Println("The number", num, " is even")
return
}
fmt.Println("The number", num, "is odd")
}()
go func() {
DemoRWM.Lock()
num++
DemoRWM.Unlock()
}()
time.Sleep(time.Second)
}
여기에서 볼 수 있듯이 두 고루틴
은 num
에 액세스하기 전에 DemoRWM.Lock()
을 호출한 다음 완료된 후에 DemoRWM.Unlock
을 호출합니다. 코드는 RWMutex
를 사용합니다.
출력을 참조하십시오.
The number 2 is even
RWMutex
가 모든 판독기가 동시에 데이터에 액세스할 수 있도록 허용하고 기록기가 다른 판독기를 잠그는 RWMutex
에 대한 또 다른 예를 시도해 보겠습니다.
예를 참조하십시오.
package main
import (
"fmt"
"sync"
)
func main() {
DemoMap := map[int]int{}
DemoRWM := &sync.RWMutex{}
go LoopWrite(DemoMap, DemoRWM)
go LoopRead(DemoMap, DemoRWM)
go LoopRead(DemoMap, DemoRWM)
go LoopRead(DemoMap, DemoRWM)
go LoopRead(DemoMap, DemoRWM)
go LoopRead(DemoMap, DemoRWM)
go LoopRead(DemoMap, DemoRWM)
go LoopRead(DemoMap, DemoRWM)
go LoopRead(DemoMap, DemoRWM)
// stop the program from exiting must be killed
StopBlock := make(chan struct{})
<-StopBlock
}
func LoopRead(DemoMap map[int]int, DemoRWM *sync.RWMutex) {
for {
DemoRWM.RLock()
for k, v := range DemoMap {
fmt.Println(k, "-", v)
}
DemoRWM.RUnlock()
}
}
func LoopWrite(DemoMap map[int]int, DemoRWM *sync.RWMutex) {
for {
for i := 0; i < 100; i++ {
DemoRWM.Lock()
DemoMap[i] = i
DemoRWM.Unlock()
}
}
}
보시다시피 RWMutex
를 사용하면 원하는 만큼 read
를 사용할 수 있습니다. 이 코드의 출력은 다음과 같습니다.
timeout running program
0 - 0
0 - 0
0 - 0
0 - 0
0 - 0
0 - 0
0 - 0
0 - 0
1 - 1
Sheeraz is a Doctorate fellow in Computer Science at Northwestern Polytechnical University, Xian, China. He has 7 years of Software Development experience in AI, Web, Database, and Desktop technologies. He writes tutorials in Java, PHP, Python, GoLang, R, etc., to help beginners learn the field of Computer Science.
LinkedIn Facebook