춤추는 개발자

[OS] 멀티 스레드의 동기화 본문

Developer's_til/운영체제

[OS] 멀티 스레드의 동기화

Heon_9u 2021. 5. 18. 17:56
728x90
반응형

앞선 포스팅에서 언급했듯이 스레드는 Stack영역을 제외한 나머지 메모리 영역을 공유합니다. 이때 공유 자원에 둘 이상의 스레드가 동시에 접근하면서 문제가 발생할 수 있습니다.

 특정 스레드가 다른 스레드에서 사용 중인 변수나 자료구조에 접근하여 예상과는 엉뚱한 값을 읽어오거나 수정하는 문제로 아래와 같은 상황이 발생합니다.

 

 이와 같이 하나의 변수에 둘 이상의 스레드가 접근하며 예상과는 다른 결과가 나올 수 있습니다. 이러한 상황을 해결하기 위한 방법이 멀티 스레드의 동기화입니다. 공유 변수에 대한 접근을 하나의 스레드로 제한함으로써 정확한 값을 리턴받을 수 있습니다. 윈도우는 다양한 동기화 관련 API를 제공하여 프로그래머가 상황에 따라 적절한 동기화 기법을 선택할 수 있습니다.

 

종류 용도
임계 영역 공유 리소스에 대해 오직 하나의 스레드 접근만 허용한다. (한 프로세스에 속한 스레드에만 사용 가능)
뮤텍스 공유 리소스에 대해 오직 하나의 스레드 접근만 허용한다. (서로 다른 프로세스에 속한 스레드에도 사용 가능)
이벤트 특정 사건 발생을 다른 스레드에 알린다.
세마포어 한정된 개수의 자원을 여러 스레드가 사용하려고 할 때, 접근을 제한한다.

 

임계 영역

- 유저 영역 메모리에 존재하는 구조체입니다. 다른 프로세스가 접근할 수 없으므로 한 프로세스에 속한 스레드 동기화에만 사용할 수 있습니다.

- 일반적인 동기화 객체보다 빠르고 효율적입니다.

- 자바에서는 임계 영역을 보호할 수 있는 메커니즘을 제공하며, 실제 스레드들이 동기화되도록 개발자가 구현해야 합니다.

 

lock, monitor, synchronized

- 동기화 문제가 발생하는 최소 단위는 객체이며, 동기화 문제 발생 지점은 객체가 소유한 내부 변수가 됩니다. 자바는 모든 객체에 락(lock or 세마포어)을 포함시키며, 모든 객체가 인스턴스화 될 때, Heap 영역에 객체가 저장될 때, 자동으로 생성됩니다.

 락은 Synchronized 키워드를 통해 사용합니다. 해당 키워드를 사용하면 객체의 락을 검사하고, 락의 현재 사용 여부를 검사함으로써 각 객체를 보호합니다.

 

스레드가 객체가 접근하는 과정

public synchronized void Method() {

}

public void normalMethod() {
	synchronizer(/* 동기화할 객체 또는 클래스 명 */) {
    	// 임계영역 코드
    }
}

변수 외에 메소드에서 일부분만 동기화하고 싶은 경우, 특정 블록 동기화 방법을 사용하면 됩니다.

 

wait(), notify(), notifyAll()

- 동기화된 블록에서 스레드 간의 통신하기 위해서는 wait(), notify(), notifyAll() 메소드를 사용해야 합니다.

- wait(): 객체에 대해 스레드를 대기하게 만듭니다.

- notify(): 객체에 대해 대기 중인 스레드가 있는 경우, 우선순위가 높은 스레드 하나만 깨웁니다.

- notifyAll(): 대기 중인 모든 스레드를 깨웁니다.

 


이벤트

- 이벤트는 대표적인 동기화 객체로 신호와 비신호라는 두 가지 상태를 가지며 코드 상에서는 Boolean값을 활용합니다.

- 특정 사건의 발생을 다른 스레드에 알리는 경우에 주로 사용합니다. 예를 들어 한 스레드가 작업을 완료한 후, 대기 중인 다른 스레드를 깨우는(호출하는) 경우가 있습니다. 즉, 한 스레드 종류 후, 다른 스레드로 시나리오를 진행할 때 이벤트를 이용합니다. 이벤트의 동기화 과정을 다음과 같습니다.

 

1. 이벤트를 비신호 상태로 생성한다.

2. 한 스레드가 작업을 진행하고, 나머지 스레드는 이벤트에 대해 Wait*()함수를 호출함으로써 이벤트가 신호 상태가 되기를 기다린다.

3. 스레드가 작업을 완료하면 이벤트를 신호상태로 바꾼다.

4. 기다리고 있던 모든 스레드가 깨어나서 작업을 진행한다.

 

 

 

 

 

 

728x90
반응형