develop
Semaphore 본문
반응형
세마포어를 사용하기 전에 세마포어가 왜 생겼는지 알아보자
하나의 자원에 접근할 때 동시에 여러 쓰레드에서 그 하나의 자원에 접근한다면?
var array = [Int]()
DispatchQueue.global().async {
for element in 0...1000 {
array.append(element)
}
}
DispatchQueue.global().async {
for element in 0...1000 {
array.append(element)
}
}
malloc: *** error for object 0x10b4d6cb0: pointer being freed was not allocated
malloc: *** set a breakpoint in malloc_error_break to debug
이렇게 에러가 난다.
이렇게 하나의 자원에 여러 곳에서 접근을 하는 것을 레이스 컨디션(Race Condition)이라고 한다.
레이스 컨디션: 한정된 자원을 동시에 이용하려는 여러 프로세스가 자원의 이용을 위해 경쟁을 벌이는 현상
동기화 방법은 크리티컬 섹션(Critical Section)이라고 한다.
임계영역 이라고도 한다.
동시 접근 문제를 해결하기 위한 동기화 기법이 세마포어, 뮤텍스 등이 있다.
- 뮤택스는 한정된 자원에 하나만 접근 가능하고
- 세마포어는 한정된 자원에 하나 이상이 접근할 수 있다.
Swift 에서는 세마포어를 사용하기 위한 DispatchSemaphore 클래스가 있다.
DispatchSemaphore를 생성할 때 자원에 접근할 수 있는 갯수를 준다.
let semaphore = DispatchSemaphore(value: 10)
이렇게 하면 10개가 자원에 접근할 수 있다.
DispatchSemaphore(value: 1)
위와 같은 코드는 하나만 자원에 접근할 수 있고 뮤택스처럼 사용할 수 있다.
DispatchSemaphore의 메서드에는
- wait: value값이 -1 작아진다.
- signal: value 값이 +1 더해진다.
value값의 0이면 자원에 접근할수 없다.
var array = [Int]()
let semaphore = DispatchSemaphore(value: 1)
DispatchQueue.global().async {
for element in 0...1000 {
semaphore.wait()
array.append(element)
semaphore.signal()
}
}
DispatchQueue.global().async {
for element in 0...1000 {
semaphore.wait()
array.append(element)
semaphore.signal()
}
}
이렇게 제일 위의 코드를 변경 하게 되면 자원을 한번씩 접근을 해서 레이스 컨디션의 문제가 일어나지 않는다.
반응형
'iOS' 카테고리의 다른 글
AutoLayout (0) | 2021.01.11 |
---|---|
Blocking, Non-blocking (0) | 2021.01.10 |
AssociatedType (0) | 2021.01.08 |
Convenience init (0) | 2021.01.07 |
LifeCycle (0) | 2021.01.06 |
Comments