티스토리 뷰

Programming Language/Go

[Go] 저수준 제어

SdardewValley 2021. 12. 31. 18:00
반응형

  Go에는 고루틴과 채널 외에도 sync 패키지를 사용하여 병행 프로그래밍이 가능하다. sync 패키지에는 공유 메모리를 제어하는 뮤텍스(mutex), sync/atomic 패키지에는 원자성을 보장할 수 있는 연산이 있다.

 

 

sync.Mutex

  뮤텍스는 공유 데이터를 보호하기 위해 사용한다. 뮤텍스 구조체는 Lock, Unlock 함수를 제공한다.

  • func (m *Mutex) Lock(): 뮤텍스 잠금
  • func (m *Mutex) Unlock(): 뮤텍스 잠금 해제

 

  임계 영역(critical section)의 코드를 실행하기 전에는 뮤텍스의 Lock() 메서드로 잠금을 하고, 실행한 후에는 Unlock() 메서드로 잠금을 해제한다.

임계 영역
병렬 컴퓨팅에서 둘 이상의 스레드가 동시에 접근해서는 안 되는 영역.

 

  위의 코드는 1씩 값을 증가하는 것을 1000번 실행하는 코드이다. 1000번 실행했으니 결과값으로는 1000이 나와야 하지만 결과 값으로는 996이 출력된다. 증가시키는 값에 필드 값을 동시에 수정하게 되어 경쟁 상태가 만들어 졌기 때문이다. 이 경우 뮤텍스를 사용해서 해결할 수 있다.

 

  sync.Mutex 값을 필드에 추가해준다. 그리고 값에 접근하여 사용할 때 Lock을 걸고 사용이 끝난뒤에는 Unlock을 해주면 된다.

 

 

sync.RWMutex

  RWMutex는 Mutex와 유사하지만 읽기 동작과 쓰기 동작을 나누어서 처리할 수 있다. 읽기 잠금을 하면 데이터를 조회할 수 있지만, 변경할 수는 없다. 쓰기 잠금을 하면 조회 및 변경 모두 불가능하다.

 

RWMutex가 제공하는 메서드

  • func (rw *RWMutex) Lock(): 쓰기 잠금
  • func (rw *RWMutex) Unlock(): 쓰기 잠금 해제
  • func (rw *RWMutex) RLock(): 읽기 잠금
  • func (rw *RWMutex) RUnlock(): 읽기 잠금 해제

 

 

sync.Once

func (o *Once) Do(f func())

  sync.Once는 특정 함수를 한 번만 수행해야 할 때 사용한다. 한 번만 수행해야 하는 함수를 메서드의 매개변수로 전달하면, 여러개의 고루틴에서 한 번만 실행된다.

 

  초기화 같은 경우에는 한 번만 필요하다. 이 경우에 sync.Once를 사용하면 된다.

 

 

sync.WaitGroup

  sync.WaitGroup은 모든 고루틴이 종료될 때까지 대기할 때 사용한다.

 

WitGroup이 제공하는 메서드

  • func (wg *WaitGroup) Add(delta int): WaitGroup에 대기 중인 고루틴 개수 추가
  • func (wg *WaitGroup) Done(): 대기 중인 고루틴의 수행이 종료되는 것을 알려줌
  • func (wg *WaitGroup) Wait(): 모든 고루틴이 종료될 때까지 대기

 

  Add로 고루틴의 개수를 증가하고, Done을 통해서 종료되는 것을 알려준다. Wait는 고루틴이 종료될 때까지 대기한다. Add로 추가한 고루틴 개수와 Done의 호출 횟수는 같아야 한다.

 

 

Atomic Operation

  Atomic Operation은 쪼갤 수 없는 연산을 말한다. 변수에 단순히 상수 1을 증가하는 연산이라도 메모리에서 변수의 값을 읽고, 연산을 수행하고, 값을 메모리에 쓰는 연산을 거친다. 고루틴은 시분할하여 실행하는 방식으로 처리된다. CPU가 이 연산을 수행하는 동안 다른 고루틴이 실행된다면 값이 변경될 수 있는 위험이 있고 동기화 문제가 발생한다.

시분할
주어진 시간을 나누어 작업을 하는 것

 

sync/atomic 패키지를 사용하면 시분할 하지 않고 한번에 처리하도록 할 수 있다.

원자성
어떤 것이 더 이상 쪼개질 수 없는 성질. 작업이 완전히 실행되어 종료되거나, 그럴 수 없는 경우 실행하지 않는 것.

 

sync/atomic이 제공하는 함수

AddT 특정 포인터 변수에 값을 더함
CompareAndSwapT 특정 포인터 변수의 값을 주어진 값과 비교하여 같으면 새로운 값으로 대체함
LoadT 특정 포인터 변수의 값을 가져옴
StoreT 특정 포인터 변수에 값을 저장함
SwapT 특정 포인터 변수에 새로운 값을 저장하고 이전 값을 가져옴

사용 예시

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
글 보관함