학습 키워드 : 스레드

Day9에서 언어에 내장되어있는 thread를 실제로 사용해보았고, 그 과정에서 Lock을 사용해 보았다. 그 과정에서 느낀 문제점하고, 해결 방법을 알아보자.

Multi-threading의 목적

스크린샷 2022-08-01 오전 10.45.38.png

스크린샷 2022-08-01 오전 10.22.33.png

성능 향상을 목표로 사용하게 된다. threading을 하게되면 호출한 이후의 stack 영역을 제외하고 나머지 영역을 공유하게 되는데, 이러한 공유 영역을 사용하는 과정에서 race condition이 발생할 수 있습니다. race condition과 같은 동기화 문제 해결을 위해 Lock, mutex 등을 이용하여 race condition을 배제하는 과정이 필요합니다.

func runThread() {
	var threadArr = [Thread]()
	
	for _ in 0..<numberOfThread {
		threadArr.append(
			Thread {
				self.lock.lock()
				defer {
					self.lock.unlock()
				}

				self.doJob()
			}
		)
		threadArr.last!.start()
	}
		
	for thread in threadArr {
		while !thread.isFinished { }
		thread.cancel()
	}
}

스크린샷 2022-08-01 오전 10.25.03.png

다시, 성능향상을 이끌려면 어떻게 해야하나

  1. Lock 을 사용하기
  2. 대규모의 연산을 멀티스레딩으로 진행하는 경우 Cache 고려

Thread with lock

Thread 자체의 입장은 단순하다. 데이터 접근을 하면 lock을 요청하여 다른 thread의 접근을 막고, lock을 획득하면 read/write를 진행을 한다. thread가 critical section을 접근할때마다 lock을 걸고 푸는 작업을 진행한다면 오류의 소지가 있고, 코드가 복잡해지기 쉽다. 그래서, thread-safe한 자료구조를 찾거나 만들어서 사용하는 경우가 잦다.

Thread-safe data structure

여러 thread가 같은 자원을 사용을 하더라도 race condition이 발생하지 않는 자료구조이다. 이런 자료구조는 메소드 내부에 lock, mutex, semaphore 등을 이용하여 작업이 thread-safe 하도록 지원해준다.