스레드 동기화 기법2
순서 동기화 즉 순서를 조절하겠다는 소리다.
순서를 동기화하는 이유가 무엇인지 아는 게 중요하다.
생산자/소비자 모델
- 데이터 입력받고 입력된 데이터 출력 구조이다.
- 입력된 크기만큼 출력되기 때문에 출력이라는 것은 입력에 의존적이다.
- 반면 입력은 외부 환경에 의존적이다.
- 여기서 발생할 문제는 10B씩 입/출력을 하다가 어느 순간 10MB가 한 번에 들어오면 10MB 데이터를 처리하다가 손실이 일어날 수 있다.
- 계속 읽기만 하면 손실이 없다. 언제 문제가 발생하냐면 읽고 출력을 하는 게 문제이다 출력하는 와중에도 데이터가 계속해서 들어오면 감당이 안 돼서 이러한 과정에서 손실이 발생할 수 있다.
- 그래서 위 이미지와 같이 입출력 모델을 설계한다.
- 입력 스레드는 계속해서 입력을 받고 출력용 버퍼에다가 데이터를 쌓는다.
- 버퍼가 견디는 한도 내에서는 출력 스레드가 버퍼에 데이터를 가져가는 속도가 느려도 문제가 없다.
- 버퍼 왼쪽에 있는 스레드를 생산자 스레드라 한다. 버퍼 오른쪽에 있는 스레드를 소비자 스레드라 한다.
- 생산자는 데이터를 제공하고(데이터를 생산하는 게 아니다.) 소비자는 데이터를 소비한다.
- 중요한 것은 순서다. 생산자가 먼저 실행이 완료되고 난 다음에 소비자가 실행이 돼야 한다.
- 생산자가 데이터를 가져다 놓기도 전에 소비자가 버퍼에 있는 데이터를 가져가면 필요 없는 데이터를 가져간 거다.
- 그래서 이러한 문제로 인해 실행 순서를 동기화하는 게 필요하다.
이벤트 기반 동기화
예시
A, B 스레드가 있고 이 두 스레드가 버퍼를 공유하고 있다고 가정해 보자.
A 스레드가 버퍼에 데이터를 쌓으면 B 스레드는 버퍼에 있는 데이터를 가져가는 구조이다.
두 스레드 간에는 A 스레드가 데이터를 가져다 두면 B 스레드가 데이터를 가져간다는 약속이 필요하다.
근데 A 스레드가 데이터를 버퍼에 가져다 놨다는 것을 B 스레드는 알 수 없다. 오직 A 스레드만 안다.
그래서 이러한 문제를 해결하기 위해 커널 오브젝트를 만들고 커널 오브젝트 상태는 nonsignaled 상태로 두고 A 스레드가 데이터를 가져다 두면 nonsignaled 상태를 signaled 상태로 바꾼다. 그러면 B 스레드는 커널 오브젝트의 상태를 감지하고 버퍼에 있는 데이터를 가져가면 된다. 그래서 B 스레드는 저 커널 오브젝트를 참조해야 한다. 그래서 WaitForSingleObject() 함수를 호출하면 된다. 생산자 스레드는 작업을 다하면 커널 오브젝트의 상태를 signaled로 바꿔야 하는데 이때 호출하는 함수가 SetEvent이다.
- 수동 리셋 모드 이벤트
- 커널 오브젝트가 signaled, nonsignaled 어떤 상태이건 이러한 상태를 일일이 수동으로 변경한다.
- 자동 리셋 모드 이벤트
- signaled을 주는 거는 수동이어야 한다. 왜냐면 생산자 스레드만이 그 타이밍을 알 수 있기 때문이다.(SetEvent는 수동이라는 의미다.)
- 이벤트 오브젝트가 signaled 상태에서 nonsignaled 상태로 돌아가는 것은 자동이다.
한순간에 하나의 스레드만 깨어나게끔 하기 위해서는 자동 리셋 모드 이벤트를 사용하면 된다.
둘 이상의 스레드가 동시에 깨어나야 하기 위해서는 수동 리셋 모드 이벤트를 사용하면 된다.
이벤트 기반 동기화 예제 확인
수동 리셋 모드 이벤트 활용의 예
임계영역이라는 것은 하나의 메모리 블록이기도 하고 둘 이상의 메모리 블록이 하나의 임계영역을 형성할 수 있다.
타이머 기반 동기화
타이머와 이벤트 오브젝트가 소프트웨어에서 어떤 의미를 지니고 있는지 보자.
타이머 기반 동기화 오브젝트는 정해진 시간이 지나면 자동으로 signaled 상태가 되는 특성을 지닌다.
타이머를 기반으로 스레드를 동기화한다는 것은 임계 영역 문제 해결을 위한 동기화와는 그 관점이 다르다.
여기서 말하는 동기화는 스레드의 실행시간 및 실행주기를 결정하겠다는 의미이다.
때문에 타이머를 스레드 동기화 부분에서 다루기 다소 애매한 부분이 없지 않다.
타이머 기반 동기화는 다음과 같이 두 가지 형태로 구분 지을 수 있다.
- 수동 리셋 타이머
- 가장 일반적인 타이머로서, 알람 시계를 생각하면 된다.
- 알람을 예시로 들면 10초 후에 한번 울리도록 수동 리셋 타이머 오브젝트를 생성할 수 있다.
- 타이머 오브젝트는 정해진 시간이 지나야 signaled 상태가 되는 커널 오브젝트이다.
- 주기적 타이머:
- 주기적 타이머는 일정 시간 간격으로 알람이 울리는 타이머를 의미한다. 수동 리셋 타이머에 주기적인 특성이 가해진 형태로 이해하며 된다.
- 알람을 6시에 맞춰 놓으면 6시에도 알람이 울리고 30분마다 한 번씩 주기적으로 알람이 울리도록 설정하는 기능이 있다. 이러한 특성의 타이머다.
- 10초 후에 매 5초마다 알람이 울리도록 주기적 타이머 오브젝트를 생성할 수 있다.
'운영체제 > 뇌를 자극하는 윈도우즈 시스템 프로그래밍' 카테고리의 다른 글
뇌를 자극하는 윈도우즈 시스템 프로그래밍 16장 (5) | 2024.09.22 |
---|---|
뇌를 자극하는 윈도우즈 시스템 프로그래밍 15장 (0) | 2024.09.21 |
뇌를 자극하는 윈도우즈 시스템 프로그래밍 13장 (1) | 2024.09.21 |
뇌를 자극하는 윈도우즈 시스템 프로그래밍 12장 (0) | 2024.09.07 |
뇌를 자극하는 윈도우즈 시스템 프로그래밍 11장 (0) | 2024.09.07 |