반응형
* 동기화 객체의 종류
- Mutex
- RWMutex
- Cond
- Once
- Pool
- WaitGroup
- Atomic
1. 뮤텍스 사용하기
func main() {
runtime.GOMAXPROCS(runtime.NumCPU())
var data = []int{} //int형 슬라이스 생
go func(){
for i := 0; i<1000; i++{
data = append(data, 1)
runtime.Gosched()
//다른 고루틴이 CPU를 사용할 수 있도록 양보
}
}()
go func() {
for i := 0; i<1000; i++{
data = append(data, 1)
runtime.Gosched()
//다른 고루틴이 CPU를 사용 할 수 있도록 양보
}
}()
time.Sleep(2 * time.Second)
fmt.Println((len(data))) //출력값 1779
}
데이터의 길이가 2000이 아닌 1779가 나왔다. 두 고로틴이 경합을 벌이면서 동시에 data에 접근했기 때문에 app end 함수가 정확하게 처리되지 않은 상황이다.
이러한 상황을 경쟁 조건(Race condition)이라고 한다.
# 데이타 슬라이스를 뮤텍스로 보호하기
func main() {
runtime.GOMAXPROCS(runtime.NumCPU())
var data = []int{}
var mutex = new(sync.Mutex)
go func() {
for i := 0; i<1000; i++ {
mutex.Lock()// 뮤텍스 잠금, data슬라이스 보호 시작
data = append(data, 1)
mutex.Unlock()
runtime.Gosched()
}
}()
go func() {
for i:=0; i<1000; i++ {
mutex.Lock()
data = append(data, 1)
mutex.Unlock()
runtime.Gosched()
}
}()
time.Sleep(2*time.Second)
fmt.Println(len(data)) // 2000출력
}
2. 읽기, 쓰기 뮤텍스 사용하기
func main() {
runtime.GOMAXPROCS(runtime.NumCPU())
var data int = 0
var rwMutex = new(sync.RWMutex) //읽기, 쓰기 뮤텍스 생성
go func() {
for i:=0; i<3; i++ {
rwMutex.Lock() //쓰기 뮤텍스 잠금, 쓰기 보호 시작
data += 1 //data에 값 쓰기
fmt.Println("write :", data)
time.Sleep(10 * time.Millisecond)
rwMutex.Unlock() //쓰기 뮤텍스 잠금 해제, 쓰기 보호 종료
}
}()
go func() {
for i:=0; i<3; i++ {
rwMutex.RLock() //읽기 뮤텍스 잠금, 읽기 보호 시작
fmt.Println("read1 :", data)
time.Sleep(1 * time.Second)
rwMutex.RUnlock()
}
}()
go func() { //값을 읽는 고루틴
for i:=0; i<3; i++ {
rwMutex.RLock()
fmt.Println("read2 :", data)
time.Sleep(2 * time.Second)
rwMutex.RUnlock()
}
}()
time.Sleep(10 * time.Second)
}
3. 조건변수 사용하기
func main() {
runtime.GOMAXPROCS(runtime.NumCPU())
var mutex = new(sync.Mutex)
var cond = sync.NewCond(mutex) //뮤텍스를 이용하여 조건변수 생성
c := make(chan bool, 3) //비동기 채널
for i := 0; i < 3; i++ {
go func(n int) {
mutex.Lock() //뮤텍스 잠금, cond.Wait()보호 시작
c <- true
fmt.Println("wait begin: ", n)
cond.Wait()
fmt.Println("wait end: ", n)
mutex.Unlock()
}(i)
}
for i := 0; i < 3; i++ {
<-c
}
for i := 0; i<3; i++ {
mutex.Lock() //뮤텍스 잠금, cond.Signal()보호 시작
fmt.Println("signal: ", i)
cond.Signal() //대기하고 있는 고루틴 들을 하나씩 깨움
mutex.Unlock()
}
fmt.Scanln()
}
반응형
'백엔드, 기타 > Golang' 카테고리의 다른 글
Golang 4. 고루틴 (0) | 2020.08.23 |
---|---|
Golang 3. 2)인터페이스 (0) | 2020.08.20 |
Golang 3. 1)포인터와 구조체 (0) | 2020.08.19 |
Golang 2. 함수 2)클로저(closure), 지연호출(defer), 패닉과 복구(panic and recover) (0) | 2020.08.15 |
Golang 2. 함수 1)함수의 리턴값/ 변수,슬라이스,맵에 함수 대응하기/클로저 (0) | 2020.08.15 |