[뇌를 자극하는 윈도우즈 시스템 프로그래밍] 2007 윤성우 저
" 시스템 프로그래이란 하드웨어를 사용할 수 있도록 도와주는 프로그램"
= Window 운영체제 기반의 컴퓨터에게 일을 시키기 위한 프로그램 구현하는 것
11. 쓰레드란 무엇인가
프로세스 : 완전히 독립된 두 개의 프로그램 실행 단위 (프로세스 사이에는 컨텍스트 스위칭이 발생)
쓰레드 : 하나의 프로그램 내에서 둘 이상의 프로그램 흐름 단위 (쓰레드 끼리 공유하는 자원이 있기 때문에 컨텍스트 스위칭에 걸리는 시간이 프로세스보다 짧다)
쓰레드 in 메모리
: 스택은 별도로 사용하되 힙, 데이터 영역은 공용으로 사용한다.
쓰레드의 생성
커널 영역이란 : 운영체제 운영을 위해 필요한 영역, 유저 영역과 같이 스택, 힙, 코드 영역으로 나뉘어 있으며 영역이 침범되면 심각한 오류가 발생되기 때문에 유저 영역과 구분되어 있다.
커널 레벨 쓰레드 : include <thread> 와 같이 운영체제에서 제공하는 쓰레드를 사용하는 경우. 커널에서 쓰레드를 관리한다.
유저 레벨 쓰레드 : 운영체제가 제공하는 쓰레드를 사용하지 않고 유저가 쓰레드를 만들어서 (순차 실행 ..etc) 사용. 커널 입장에서는 하나의 프로세스만 굴러가는 것처럼 보인다.
12. 쓰레드의 생성과 소멸
CreateThread(,,,,)
* 메인 쓰레드가 종료되면 그 안에 있는 쓰레드들은 종료되지 않는다. 자식 쓰레드들의 자체적인 종료를 권장한다.
** 현재 컴에서 최대 1060개 생성 가능
*** 마이크로소프트에서 생성 가능한 최대 쓰레드가 2024라고 발표했다.
**** 쓰레드 스택을 아주 작게 요구하면 무조건 1M로 지정한다.
* 쓰레드에서 입출력 관련 업무는 block을 많이 요구한다. (입출력하러 간 사이 CPU는 놀게 됨) 이 작업을 조금이라도 빨리 끝내기 위해서는 쓰레드를 만들어 쉬는 틈 없이 일을 시키도록 한다.
* 실행 중인 프로세스의 종료를 기다리는 함수 WaitForMultipleObjects(....)
* 해당 쓰레드에서 반환한 리턴값 받는 함수 GetExitCodeThread(....)
* 강제 종료 쓰레드 함수 ExitThread(...) : 하지만 각 쓰레드의 소멸자는 호출되지 않아 메모리 유출 현상이 발생할 수 있으니 주의해야 한다.
* 쓰레드가 전역 변수(공용)에 동시에 접근할 경우
계산 결과를 저장하기 전에 다른 스레드에 의해 값이 변할 수 있음을 주의
* CloseHandle
Usage Count는 쓰레드 생성할 때 2개가 생긴다. (핸들, 쓰레드 생성) 핸들을 바로 닫아주면 Usage Count 가 1이 된다. 쓰레드가 종료되면 0이 되어 모든 메모리가 반환된다. (쓰레드 종료되는 시점에 리소스 반환 가능)
(OS에서 알아서 닫아준다는 이야기가 있는데 진위여부 판단이 안됨)
****표준 C 라이브러리는 쓰레드에 대한 고려가 되어 있지 않다. strtock같은 함수를 사용할 경우 동일한 메모리 영역을 동시에 접근하는 불상사가 발생할 수 있다.
이를 위해 마이크로 소프트에서는 ANSI라는 포준 라이브러리를 제공하고 있다. 따라서 CreateThread보다 beginThread를 사용하는 것이 안전하다.(내부적으로 독립적인 메모리 블록을 할당한다.)
13. 쓰레드 동기화 기법
쓰레드 동기화 : 쓰레드의 실행순서를 정의하고 이 순서에 반드시 따르도록 하는 것.
쓰레드 동기화 두 가지 방법
1. 유저 모드 동기화
: 커널에서 제공하는 동기화 기능 사용 안함.
: 크리티컬 섹션, 인터락
2. 커널 모드 동기화
: 커널에서 제공하는 동기화 기능 사용.
: 뮤텍스, 세마포어, 이름있는 뮤텍스, 이벤트 기반
1. 유저 모드 동기화
1) 크리티컬 섹션 동기화
: 열쇠를 가진 자만이 임계 영역에 들어갈 수 있게 허용하는 것
2) 인터락 함수 기반 동기화
InterLockIncrement(,,,,)
InterLockDecrement(,,,,,)
한 순간 하나의 쓰레드만 접근하는 것을 보장해주는 함수
-volatile 키워드 : 최적화를 수행하지 마라. 메모리에 직접 연산하라(캐시 되지 않음)
3) 뮤텍스 동기화
CreateMutex(,,,,)
: 실행 가능한 상태가 될 때 signaled 상태가 된다.
: 임계 영역 들어갈 때 non-signaled, 임계 영역 빠져나올 때 signaled
4) 세마포어 동기화
카운트 기능 : 임계 영역에 동시 접근할 수 있는 쓰레드 갯수를 N개로 한정하는 것
14. 쓰레드 동기화 기법 2
2. 커널 모드 동기화
1) 이벤트 동기화
CreateEvent(...)
: 이벤트 커널 오브젝트는 프로그래머의 요청에 의해 signaled가 된다.
: 즉 무언가를 하고 끝났을 때 이를 감지하고 다음이 시작된다.
: Non-Signaled 상태의 오브젝트 때문에 WaitForSingleObject 함수 호출이 블로킹되었다면 signaled 상태가 되는 순간 블로킹된 함수를 빠져나오게 된다.
수동 리셋 이벤트 : signaled가 되는 순간을 조정 가능(둘 이상을 제어할 때 필요)
자동 리셋 이벤트 : non-signaled ->signaled ->non-signaled 자동으로 상태 변화됨
이벤트(Event) + 뮤텍스(Mutex) :
개념 :
생산자 하나에 소비자가 둘이다.
생산자가 생산하고 나면 소비자 둘은 동기화를 통해 소비해야 한다.
사용법 :
1. 생산자와 소비자 간의 이벤트 기반 동기화를 한다. (실행순서 동기화)
2. 소비자간의 임계 영역에 뮤텍스(임계 영역 동기화 기법)로 동기화한다. (메모리 접근 동기화)
출처: https://dakuo.tistory.com/97 [hacker dakuo]
2. 타이머 기반 동기화
정해진 시간이 지나면 자동으로 signaled 되는 것
: 쓰레드의 실행 시간, 주기를 설정한다는 의미
'Programming' 카테고리의 다른 글
윈도우 시스템 프로그래밍_7 (0) | 2020.10.18 |
---|---|
윈도우 시스템 프로그래밍_6 (0) | 2020.10.11 |
윈도우 시스템 프로그래밍_4 (0) | 2020.09.26 |
윈도우 시스템 프로그래밍_3 (0) | 2020.09.21 |
윈도우 시스템 프로그래밍_2 (0) | 2020.09.13 |