11장 윈도우 스레드 풀

40
11 장 장장장 장장장 장 12 장 장장장 장장장 (http://cafe.naver.com/architect1) 장장장 (twitter.com/jun0683)

Upload: -

Post on 11-Jun-2015

1.051 views

Category:

Technology


4 download

TRANSCRIPT

Page 1: 11장 윈도우 스레드 풀

11 장 윈도우 스레드 풀12 장 파이버

아꿈사 (http://cafe.naver.com/architect1)김홍준 (twitter.com/jun0683)

Page 2: 11장 윈도우 스레드 풀

11 장 윈도우 스레드 풀- 비동기 함수 호출 ( 스레드 )- 시간 간격을 두고 함수 호출 ( 타이머 )- 커널 오브젝트가 시그널 되면 함수 호출 ( 이벤트 )- 비동기 I/O 요청 완료되면 함수 호출 (IOCP)

12 장 파이버

Page 3: 11장 윈도우 스레드 풀

11 장 윈도우 스레드 풀- 비동기 함수 호출 ( 스레드 )- 시간 간격을 두고 함수 호출 ( 타이머 )- 커널 오브젝트가 시그널 되면 함수 호출 ( 이벤트 )- 비동기 I/O 요청 완료되면 함수 호출 (IOCP)

12 장 파이버

Page 4: 11장 윈도우 스레드 풀

윈도우 스레드 풀이란 ? 스레드 생성 , 파괴 , 관리작업을 좀 더

쉽게구현 할 수 있도록 제공 ( 책에서는 비스타 이상 )

어렵지 않아요 ~

Page 5: 11장 윈도우 스레드 풀

비동기 함수 호출 ( 스레드 ) 를 뙇 !

VOID NTAPI SimpleCallback( PTP_CALLBACK_INSTANCE pIn-stance, PVOID pvContext);

사용자 정의

BOOL TrySubmitThreadpoolCallback( PTP_SIMPLE_CALLBACK pfnCallback, PVOID pvContext, PTP_CALLBACK_ENVIRON pcbe);

사용자 정의 함수작업 요청 ( 비동기적으로 )

Page 6: 11장 윈도우 스레드 풀

TrySubmitThreadpoolCallback()

이분을 쓰면 CreateThread X

스레드 일일이 생성 파괴 관리 X => 알아서 재사용 => 알아서 스레드 개수 증가 감소

Page 7: 11장 윈도우 스레드 풀

명시적 작업 항목 제어

TrySubmitThreadpoolCallback 실패시( 메모리 부족 , 메모리 할당제한등 ..)

Page 8: 11장 윈도우 스레드 풀

명시적 작업 항목 제어

스레드 풀에서 작업 항목이 들어 가지 않는다면 ?

내부적으로 작업 항목을 새로 생성 한 후작업 항목을 스레드 풀 큐에 넣음 => 작업 항목 큐를 이용하자 !

Page 9: 11장 윈도우 스레드 풀

명시적으로 작업 항목을 제어 하려면1. 작업 항목 만들고2. 큐에 넣고

0. 작업 할 콜백함수 구현

1. 콜백 함수 원형 넣고 작업 항목 만듦

PTP_WORK CreateThreadpoolWork( PTP_WORK_CALLBACK pfnWorkHan-dler, PVOID pvContext, PTP_CALLBACK_ENVIRON pcbe);

VOID CALLBACK WorkCallback( PTP_CALLBACK_INSTANCE Instance, PVOID Context, PTP_WORK Work);

VOID SubmitThreadpoolWork(PTP_WORK pWork);

2. 큐에 넣기

Page 10: 11장 윈도우 스레드 풀

명시적 작업 항목 제어

삽입한 장업항목을 취소하거나처리될때까지 특정 스레드를 대기상태

VOID WaitForThreadpoolWorkCall-backs(PTP_WORK pWork,BOOL bCancelPendingCallbacks);

True 면 취소 , 처리중이라면 취소하지 않고 처리될때 까지 대기False 면 완전히 처리 될떄까지 대기

Page 11: 11장 윈도우 스레드 풀

명시적 작업 항목 제어

VOID CloseThreadpoolWork(PTP_WORK pwk);

작업 항목이 더 이상 필요 없다면작업 항목 제거

Page 12: 11장 윈도우 스레드 풀

데모

Page 13: 11장 윈도우 스레드 풀

11 장 윈도우 스레드 풀- 비동기 함수 호출 ( 스레드 )- 시간 간격을 두고 함수 호출 ( 타이머 )- 커널 오브젝트가 시그널 되면 함수 호출 ( 이벤트 )- 비동기 I/O 요청 완료되면 함수 호출 (IOCP)

12 장 파이버

Page 14: 11장 윈도우 스레드 풀

시간 간격을 두고 함수 호출 ( 타이머 ) 를 뙇 !

VOID CALLBACK TimeoutCallback(PTP_CALLBACK_INSTANCE pInstance, PVOID pvContext,PTP_TIMER pTimer);

PTP_TIMER CreateThreadpoolTimer(PTP_TIMER_CALLBACK pfnTimerCall-back,PVOID pvContext,PTP_CALLBACK_ENVIRON pcbe)

타이머 함수 원형

타이머 생성

타이머 스레드 풀에 등록

VOID SetThreadpoolTimer(PTP_TIMER pTimer,PFILETIME pftDueTime,DWORD msPeriod,DWORD msWindowLength);

Page 15: 11장 윈도우 스레드 풀

시간 간격을 두고 함수 호출

콜백 함수가 정확한 시간에 호출 해주는 것 보다 스레드를 깨웠다가 다시 대기 상태로 만드는 비용을 줄이는 것이 중요

타이머를 한번 만들고 SetThread-poolTimer()

을 이용해서 시간 조작

Page 16: 11장 윈도우 스레드 풀

시간 간격을 두고 함수 호출

pftDueTime 을 NULL 로 넣으면타이머 호출 X타이머 오브젝트를 파괴 하지 않고 타이머 정지 가능

VOID SetThreadpoolTimer(PTP_TIMER pTimer,PFILETIME pftDueTime,DWORD msPeriod,DWORD msWindowLength);

Page 17: 11장 윈도우 스레드 풀

시간 간격을 두고 함수 호출

삽입한 타이머을 취소하거나처리될때까지 특정 스레드를 대기상태

VOID WaitForThreadpoolTimerCall-backs(PTP_WORK pWork,BOOL bCancelPendingCallbacks);

True 면 취소 , 처리중이라면 취소하지 않고 처리될때 까지 대기False 면 완전히 처리 될떄까지 대기

Page 18: 11장 윈도우 스레드 풀

11 장 윈도우 스레드 풀- 비동기 함수 호출 ( 스레드 )- 시간 간격을 두고 함수 호출 ( 타이머 )- 커널 오브젝트가 시그널 되면 함수 호출 ( 이벤트 )- 비동기 I/O 요청 완료되면 함수 호출 (IOCP)

12 장 파이버

Page 19: 11장 윈도우 스레드 풀

커널 오브젝트가 시그널 되면 함수 호출( 이벤트 ) 를 뙇 !

VOID CALLBACK WaitCallback(PTP_CALLBACK_INSTANCE pInstance, PVOID Context,PTP_WAIT Wait,TP_WAIT_RESULT WaitResult);

PTP_WAIT CreateThreadpoolWait(PTP_WAIT_CALLBACK pfnWaitCall-back,PVOID pvContext,PTP_CALLBACK_ENVIRON pcbe);

VOID SetThreadpoolWait(PTP_WAIT pWaitItem,HANDLE hObject,PFILETIME pftTimeout);

시그널 대기 함수 원형

시그널 대기 함수 생성

스레드 풀에 등록

Page 20: 11장 윈도우 스레드 풀

커널 오브젝트가 시그널 되면 함수 호출

핸들 오브젝트를 사용시그널 상태가 됬을 때 콜백 함수를 호출

VOID SetThreadpoolWait(PTP_WAIT pWaitItem,HANDLE hObject,PFILETIME pftTimeout);

Page 21: 11장 윈도우 스레드 풀

커널 오브젝트가 시그널 되면 함수 호출

내부적으로 스레드 풀은WaitForMultipleObjects 을 이용하기 때문64 개만 대기 가능

동일한 커널 오브젝트를 동시에 여러 번사용이 안되므로 DuplicateHandle 을 이용복사된 핸들을 각각 등록

Page 22: 11장 윈도우 스레드 풀

커널 오브젝트가 시그널 되면 함수 호출

프로세스 커널 오브젝트는 한번 시그널이면영원히 시그널 상태SetThreadpoolWait 호출할때 다른

오브젝트또는 Null 값을 전달해서 해당 핸들을 제거

Page 23: 11장 윈도우 스레드 풀

커널 오브젝트가 시그널 되면 함수 호출

콜백 함수 내에서 WaitForThreadpoolWork호출 하면 데드락

SetThreadpoolWait 매개 변수로 전달한커널 오브젝트는 삭제 하면 안됨 !

Page 24: 11장 윈도우 스레드 풀

커널 오브젝트가 시그널 되면 함수 호출

대기중인 커널 오브젝트에 대해PulseEvent 같은 시그널 함수 호출도 안됨 !해당 이벤트가 호출한 시점에 대기 하고 있음을 보장을 못함 !

Page 25: 11장 윈도우 스레드 풀

11 장 윈도우 스레드 풀- 비동기 함수 호출 ( 스레드 )- 시간 간격을 두고 함수 호출 ( 타이머 )- 커널 오브젝트가 시그널 되면 함수 호출 ( 이벤트 )- 비동기 I/O 요청 완료되면 함수 호출 (IOCP)

12 장 파이버

Page 26: 11장 윈도우 스레드 풀

비동기 I/O 요청 완료되면 함수 호출 (IOCP) 뙇 !

10 장에 대략적으로 다룸

어떤 함수를 호출 할지를 지정하기만 하면 됨

Page 27: 11장 윈도우 스레드 풀

비동기 I/O 요청 완료되면 함수 호출 (IOCP)

VOID CALLBACK OverlappedComple-tionRoutine(PTP_CALLBACK_INSTANCE pInstance, PVOID pvContext,PVOID pOverlapped,ULONG IoResult,ULONG_PTR NumberOfBytesTrans-ferred,PTP_IO pIo);

I/O 작업 완료시 호출되는 함수 원형

PTP_IO CreateThreadpoolIo(HANDLE hDevice,PTP_WIN32_IO_CALLBACK pfnIoCall-back,PVOID pvContext,PTP_CALLBACK_ENVIRON pcbe);

스레드 풀 I/O 오브젝트 생성파일 / 장치 핸들값을 넣어줌

Page 28: 11장 윈도우 스레드 풀

비동기 I/O 요청 완료되면 함수 호출 (IOCP)

VOID StartThreadpoolIo(PTP_IO pio);

VOID CancelThreadpoolIo(PTP_IO pio);

VOID CloseThreadpoolIo(PTP_IO pio);

단 , 풀에 넣고 나서 READ/WRITE 할것

I/O 오브젝트와 스레드 풀 연동

I/O 작업이 실패 하면 반드시 호출

사용을 마치려면 …I/O 오브젝트 닫기

Page 29: 11장 윈도우 스레드 풀

비동기 I/O 요청 완료되면 함수 호출 (IOCP)

VOID WaitForThreadpoolIoCallbacks(PTP_IO pio,BOOL bCancelPendingCallbacks);

I/O 작업이 완료 될때까지 다른 스레드가 대기 시킴

True 면 시작 되지 않은 모든 요청을 취소 완료 통지도 발생 X

Page 30: 11장 윈도우 스레드 풀

+@ 콜백 종료 동작

콜백 함수가 종료 될때 쓰면 유용

스레드 풀이 종료시 자동적으로 호출

LeaveCriticalSectionWhenCallbackReturns

ReleaseMutexWhenCallbackReturns

ReleaseSemaphoreWhenCallbackReturns

SetEventWhenCallbackReturns

FreeLibraryWhenCallbackReturns

Page 31: 11장 윈도우 스레드 풀

스레드 풀 커스터마이징 뙇 !

스레드 풀에서 동작하는 스레드의 최소 최대 개수를 설정OR스레드 풀을 각각 독립적으로 생성 , 파괴

Page 32: 11장 윈도우 스레드 풀

스레드 풀 커스터마이징

PTP_POOL CreateThreadpool(PVOID reserved);

BOOL SetThreadpoolThreadMinimum(PTP_POOL pThread-Pool, DWORD cthrdMin);BOOL SetThreadpoolThreadMaximum(PTP_POOL pThread-Pool, DWORD cthrdMost);

VOID CloseThreadpool(PTP_POOL pThreadPool);

기본 스레드 풀은 최소 스레드 1 개 최대 500 개를 가짐

Page 33: 11장 윈도우 스레드 풀

11 장 윈도우 스레드 풀- 비동기 함수 호출 ( 스레드 )- 시간 간격을 두고 함수 호출 ( 타이머 )- 커널 오브젝트가 시그널 되면 함수 호출 ( 이벤트 )- 비동기 I/O 요청 완료되면 함수 호출 (IOCP)

12 장 파이버

Page 34: 11장 윈도우 스레드 풀

파이버라 쓰고 코루틴이라 읽는다…

코루틴은 마치 예전 OS 의 비선점형 (non-preemptive) 쓰레드와 비슷하게 동작

프로그래머가 강제로 컨텍스트 스위칭 명령을 줘야 스위칭

Page 35: 11장 윈도우 스레드 풀

파이버

기존 UNIX 프로그램을 포팅하기 위해서…윈도우는 그냥 스레드 쓰면 됨… .

유저모드에서 돌아서 가볍다스케줄링을 직접 해야 함

Page 36: 11장 윈도우 스레드 풀

파이버 함수 사용

PVOID ConvertThreadToFiberEx(PVOID pvParam,DWORD dwFlags);

기존 스레드를 파이버로 변경

파이버 단위에는 부동소수점 상태 정보를 포함하지 않으므로플래그에 FIBER_FLAG_FLOAT_SWITCH 를 넣어줌

ConvertThreadToFiber

Page 37: 11장 윈도우 스레드 풀

파이버 함수 사용

새로운 파이버를 생성리턴 받은 컨텍스트 정보를 저장 해두고 사용

PVOID CreateFiberEx(SIZE_T dwStackCommitSize,SIZE_T dwStackReserveSize,DWORD dwFlags,PFIBER_START_ROUTINE pStartAd-dress,PVOID pvParam);

VOID WINAPI FiberFunc(PVOID pvParam); 파이버 함수 원형

Page 38: 11장 윈도우 스레드 풀

파이버 함수 사용

VOID SwitchToFiber(PVOID pvFiberExecutionCon-text);

바이퍼 간 스위칭

컨텍스트 정보를 이용해서 스위칭을 함

PVOID GetCurrentFiber(); 현재 컨텍스트 주소를 얻어옴

Page 39: 11장 윈도우 스레드 풀

데모

Page 40: 11장 윈도우 스레드 풀

끝 !