관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - swift] NSLock(), Thread Safe 개념 본문

iOS 기본 (swift)

[iOS - swift] NSLock(), Thread Safe 개념

jake-kim 2022. 4. 28. 23:42

Thread Safe

  • 멀티 스레드 프로그래밍에서 instance나 method에 여러 스레드가 동시에 접근이 이루어져도 프로그램 실행에 문제가 없는 것
    • ex) thread safe하지 않은 경우, 증상 중 하나 deadlock
    • 자원을 점유하고 있으면서 동시에 다른 자원을 요청하여 계속 wait하는 상태

deadlock

  • Thread-safe 지키는 방법
    • Re-entrancy
      • 어떤 method가 한 스레드에 의해 호출되어 실행중일 때, 다른 스레드가 이 method를 호출하더라도 그 결과가 각각에게 올바르게 주어짐
    • Thread-local storage ( = Immutable Objects)
      • 공유 자원을 최대한 줄여서 동시 접근을 막는 방법
    • mutual exclusion
      • 공유 자원을 사용하는 경우, 해당 자원의 접근을 semophore등의 lock으로 통제하여 다른 스레드가 접근하지 못하게하여 임계 영역 안에서 한가지 스레드만 접근
    • atomic operations
      • 각 연산이 중단되지 않고 한번에 실행되는것을 의미
      • 두 명의 사용자가 프린터 출력 명령 -> 각 인쇄는 중단되지 않고 한번에 실행
      • 만약 atomic이 아닌 경우, 두 사용자의 자료를 부분적으로 인쇄되는 문제

스위프트의 NSLock 개념

  • Thread-safe 지키는 방법 중 하나인 atomic operations을 위한 방법
  • 보통 defer 키워드와 같이 사용하여 lock 후에 unlock하여 연산을 atomic하게 만들도록 하기 위함
    • 만약 unlock호출을 하지 않게되면 deaklock 발생 (특정 연산을 계속 점유하지만 끝나지 않아서 다른 스레드가 계속 기다리는 형태)

NSLock 사용 방법

  • atomic operation이 아닌 코드 준비
    • thread 2개 (global 2개)
    • 하나의 메소드에 2개 thread가 동시에 접근했으므로 atomic하지 않은 연산으로 진행
    • 출력에서 둘 다 9980값이 나오는 현상 발생
class ViewController: UIViewController {
  var value = 10000
  
  override func viewDidLoad() {
    super.viewDidLoad()
    
    DispatchQueue.global().async {
      self.subtractionTen()
    }
    
    DispatchQueue.global().async {
      self.subtractionTen()
    }
  }
  
  func subtractionTen() {
    self.value -= 10
    print(self.value)
  }
}

/*
9980
9980
*/
  • lock을 사용하여 9990, 9980이 나오도록 변경
class ViewController: UIViewController {
  var value = 10000
  let lock = NSLock()
  
  override func viewDidLoad() {
    super.viewDidLoad()
    
    DispatchQueue.global().async {
      self.subtractionTen()
    }
    
    DispatchQueue.global().async {
      self.subtractionTen()
    }
  }
  
  func subtractionTen() {
    self.lock.lock()
    defer { self.lock.unlock() }
    
    self.value -= 10
    print(self.value)
  }
}

/*
9990
9980
*/

* 참고

https://gompangs.tistory.com/entry/OS-Thread-Safe%EB%9E%80

Comments