SlideShare a Scribd company logo
1 of 68
최윤종
   TLS(Thread Local Storage)
   스레드 동기화
   커널 객체를 이용한 동기화
   스레드 스케줄링
   스레드 단위의 전역 변수
   다른 스레드와 완전히 분리되는 변수
   매개변수 대체
    ◦ 매개변수의 개수를 무작정 늘리지 않습니다
    ◦ 원형이 정해져있는 콜백 함수에서 참조 대용
   TLS 지원
    ◦ Win32 TLS, Compiler TLS, MFC TLS
Thread 1                 some()
tls(value)              tls(value)
some() 호출                return                some()
                                              tls(value)



               tls
             value1
                                       tls
                                     value2


                      Thread 2                   some()
                      tls(value)                tls(value)
                      some() 호출                  return
변수            함수               스레드


지역 변수        함수마다 독립          스레드마다 독립


정적 변수      모든 함수에서 공유        전체 스레드에서 공유


 TLS    같은 스레드의 모든 함수에서 공유    스레드마다 독립
Thread 1       Thread 2
0    INUSE           0     data 1   0       …
1    INUSE           1       …      1     data 1
2     FREE           2       …      2       …
       …                     …              …
       …                     …              …
…      …             …       …      …       …
       …                     …              …
       …                     …              …
n      …             n       …      n       …
  TLS Bit Flags             TLS            TLS

n : Windows 95/NT = 64
   Windows 98/ME = 80
   Windows 2000/XP = 1088
   TLS Bit Flags 배열은 INUSE, FREE값 저장
    ◦ 사용중, 사용가능
    ◦ 실제 사용중인 것은 아니고 개념적인 것
   초기 Bit Flags TLS 배열의 인덱스 할당
    ◦ TlsAlloc()
   TLS Bit Flags 배열의 비트 플래그 해제
    ◦ TlsFree(dwTlsIndex)
   TlsGetValue(index), TlsSetValue(index, value)
   TLS 배열에서 FREE인 인덱스 반환
   TLS는 n * 4Byte 배열 n :Windows 98/ME = 80
                         Windows 95/NT = 64

    ◦ sizeof(void *)?       Windows 2000/XP = 1088
   초기 TLS는 0으로 초기화되어있음
   반환/설정 값은 적절한 자료형으로 캐스팅
   자료형이 4Byte를 넘어갈 경우 Boxing
    ◦ TLS 배열에는 포인터 형태로 저장
   접근하는 값은 다른 스레드와 상호 배타
   TLS Bit Flags를 INUSE에서 FREE로 설정
   TLS Bit Flags 배열과 TLS 배열은 다릅니다
    ◦ 배열 항목 개수가 동일합니다
    ◦ TLS 배열은 스레드마다 할당
   컴파일러에서 키워드 형태로 지원
   __declspec(thread) 자료형 변수명
    __declspec(thread) int k;
   컴파일 단계에서 .tls 섹션으로 통합
   스레드 생성 시 .tls에서 동적 할당
    ◦ 컴파일러가 접근 코드를 삽입
   선언만 다르고 나머지는 변수와 같습니다.
   TLS가 필요없는 스레드도 TLS 할당
   컴파일러의 TLS 접근 코드 삽입
    ◦ 추가 오버헤드 발생
   LoadLibrary로 DLL을 로드하는 경우 사용 불가
   TLS를 사용하는 클래스는 CNoTrackObject 클래
    스 상속
   THREAD_LOCAL 매크로를 사용하여 선언
   접근은 항상 -> 연산자
    ◦ 연산자 오버로딩되어 있습니다
      class CTls1 : public CNoTrackObjecct
      {
      public:
         int x, y;
      };

      THREAD_LOCAL(CTls1, tls1);
      tls1->x = 10;
   내부적으로 Win32 TLS를 사용
   초기화는 내부에서 처리
    ◦ 최초 접근시 초기화
   CNoTrackObject, CThreadLocalObject,
    THREAD_LOCAL
    ◦ MSDN에 정식 등재된 클래스/매크로가 아님
   스레드 안전 함수
    ◦ 원자적 실행이 보장되는 함수
   ANSI C의 스레드 안전하지 않은 함수
    ◦ strtok, strerror, tmpnam, tmpfile, asctime, …
   스레드 안전하게 보강된 라이브러리 사용
    ◦ LibC.lib, LibCD.lib, LibCMt.lib, LibCMtD.lib,
      MSCVRt.lib, MSCVRtD.lib
    ◦ ~D.lib는 디버그 모드용 버전
   _threadstartex()
    ◦ 최초 TLS 관리 객체 초기화
    ◦ 내부적으로 _endthreadex() 호출
   _beginthreadex()
    ◦ 내부적으로 _threadstartex() 호출
   _beginthreadex() 권장
   원자적 연산 수행
    ◦ 변수에 대한 접근이 자유롭지만 특정 순간에는 하나의 스
      레드만 접근하여 연산 수행
   문맥 교환 시점에 따라 원자적 수행이 불가능
전역(정적) 변수 자료형   동기화 방법
정수, 포인터         Interlocked- 함수, volatile
기타              동기화 객체
   정수형 자료형에 대한 원자적인 연산
    ◦ 프로그램에서 가장 많이 접근하는 자료형
    ◦ int, long, void *, …
   LONG InterlockedIncrement(LONG volatile
    *lpAddend)
   LONG InterlockedDecrement(LONG volatile
    *lpAddend)
    ◦ lpAddend 매개변수를 1 증가 혹은 감소
   Long InterLockedExchangeAdd(LPLONG volatile
    Addend, LONG Value)
    ◦ Addend로 받은 주소에 Value 값만큼 증감
   Long InterLockedExchange(LONG volatile *Target,
    LONG Value)
    ◦ Target으로 받은 주소에 Value 값 대입
   Long InterLockedCompareExchange (LONG
    volatile *Destination, LONG Exchange, LONG
    Comperand)
    ◦ Destination의 실제 값과 Comperand의 값이 같은 경우
      Exchange를 Destination의 실제 값에 대입
    ◦ if(*Destination == comperand)
         *Destination = Exchange;
   PVOID InterlockedExchangePointer
   PVOID InterlockedExchangePointer(PVOID
    volatile *Target, PVOID Value)
    ◦ Target의 포인터 값을 Value 포인터로 변경
   PVOID
    InterlockedCompareExchangePointer(PVOID
    volatile *Destination, PVOID Exchange, PVOID
    Comperand)
    ◦ Destination의 포인터 값이 Comperand값과 같다면
      Destination의 포인터 값에 Exchange포인터로 변경
   휘발성 변수를 선언할 때 사용
    ◦ 코드 상에서 명시적으로 대입하는 것이 아닌 실제 CPU에
      서 대입하게 하는 변수
   컴파일러의 최적화 방지
    ◦ 컴파일러는 최적화 과정에서 불필요한 연산을 하는 코드
      를 감지, 삭제
    ◦ volatile 키워드는 변수에 대한 연산 시 최적화에 의해 삭
      제되는 코드를 삭제하지 못하게 막음
   모든 전역 변수와 하드웨어와 매핑되는 변수에 사용
   기계상으로 특정 주소에 위치한 장치에 대해 항상
    값을 읽어올 때 사용

   volatile을 생략한 경우
    ◦ disassembly
   모든 전역 변수와 하드웨어와 매핑되는 변수에 사용
   기계상으로 특정 주소에 위치한 장치에 대해 항상
    값을 읽어올 때 사용

   volatile을 명시한 경우
    ◦ disassembly
동기화 객체                            특징
                   • 작고 빠르다
critical section   • 소유 개념이 있고 중복 소유가 가능하다
                   • 프로세스 사이에 공유되지 않는다
                   •   크리티컬 섹션에 비해 무겁다
                   •   시그널, 논 시그널 개념이 있다
    event
                   •   자동과 수동 이벤트 개념이 있다
                   •   프로세스 사이에 공유될 수 있다
                   • 크리티컬 섹션에 비해 무겁다
 semaphore         • 시그널 카운트 개념이 있다
                   • 프로세스 사이에 공유될 수 있다
                   • 크리티컬 섹션에 비해 무겁다
    mutex          • 소유 개념이 있고 중복 소유가 가능하다
                   • 프로세스 사이에 공유될 수 있다
   CRITICAL_SECTION cs
   LPCRITICAL_SECTION lpcs
    ◦ 크리티컬 섹션 객체와 그 포인터


   void InitializeCriticalSection(lpcs)
    ◦ 크리티컬 섹션 객체 초기화
   void DeleteCriticalSection(lpcs)
    ◦ 크리티컬 섹션 객체 해제
   void EnterCriticalSection(lpcs)
    ◦ 크티티컬 섹션 진입, 최대 30일 대기
   BOOL TryEnterCriticalSection(lpcs)
    ◦ 진입 시도를 하여 성공하면 TRUE를 반환
   void LeaveCriticalSection(lpcs)
    ◦ 크리티컬 섹션 탈출


   중복 진입 가능
    ◦ 탈출할 때에는 반드시 중복 진입한 수만큼 탈출
   커널 객체는 프로세스간 동기화도 가능
    ◦ OpenEvent(), OpenMutex(), OpenSemaphore()
      인자에 이름을 넣습니다
      이름은 각 객체에 대한 설명 때 나옵니다
    ◦ 대신에 크고 무겁습니다


   시그널 상태
    ◦ 실행 대기중인 상태(잠자고 있습니다)
   논 시그널 상태
    ◦ 현재 실행중인 상태(깨어 있습니다)
   DWORD WaitForSingleObject(HANDLE hHandle,
    DWORD dwMilliseconds)
    ◦ 커널 객체 hHandle에 대해 dwMilliseconds만큼 대기
    ◦ 시그널에서 논 시그널이 될 때까지 대기
   크기가 nCount인 lpHandles 배열의 핸들들을
    dwMilliseconds만큼 대기
   bWaitAll이 TRUE면 모든 스레드가 시그널 될 때까
    지 대기
   마지막 인자 dwMilliseconds를 통해 무제한
    (INFINITE) 대기 가능
   시그널 상태인지만 검사하는 경우 마지막 인자
    dwMilliseconds에 0 대입
   반환값
    ◦ WAIT_OBJECT_0 : 시그널로 전환됨
    ◦ WAIT_TIMEOUT : 시간 초과
    ◦ WAIT_ABANDONED_0 : 기다리던 스레드가 종료됨
      mutex 전용
    ◦ WAIT_FAILED : 잘못된 hHandle 인자
   가장 원시적인 커널 객체
   자동 리셋 이벤트
    ◦ 대기하던 스레드가 시그널 될 때 이벤트 객체가 자동으로
      논 시그널 됨
   수동 리셋 이벤트
    ◦ 대기하던 스레드가 시그널 되더라도 이벤트 객체는 유지됨
    ◦ BOOL ResetEvent(HANDLE hEvent)로 이벤트 객체를 논
      시그널로 전환
// 생성된 이벤트 핸들




   lpEventAttributes : 속성
   bManualReset : 자동/수동
   bInitialState : 시그널/논 시그널
   lpName : 이벤트 이름
   BOOL SetEvent(HANDLE hEvent)
   BOOL ResetEvent(HANDLE hEvent)
   hEvent 이벤트를 Set(시그널), Reset(논 시그널)
   자동 이벤트와 크리티컬 섹션을 비교합니다

           자동 이벤트                            크리티컬 섹션
CreateEvent(NULL, FALSE, TRUE,   InitializeCriticalSection
NULL)
WaitFor-                         EnterCriticalSection
SetEvent                         LeaveCriticalSection
Closehandle                      DeleteCriticalSection
   WaitForMultipleObject와 동일합니다
   마지막 인자 dwWakeMask
    ◦ QS_ALLINPUT을 대입하면 메세지 큐의 모든 이벤트 대기
   뮤텍스 획득 = 논 시그널과 유사
   뮤텍스 해제 = 시그널과 유사




   두번째 인자 bInitalOwner가 TRUE면 생성 직후 뮤
    텍스를 획득
   BOOL ReleaseMutex(HANDLE hMutex)
    ◦ 뮤텍스 hMutex를 해제
   WaitFor-함수의 반환값 WAIT_ABANDONED_0
    ◦ 뮤텍스를 소유하던 WAIT_ABANDONED_0(배열상의 +n
      번째) 스레드가 종료되어 논 시그널 상태가 된 경우
   뮤텍스와 이벤트, 크리티컬 섹션을 비교합니다

    뮤텍스              자동 이벤트                      크리티컬 섹션
CreateMutex   CreateEvent(NULL, FALSE,   InitializeCriticalSection
              TRUE, NULL)
WaitFor-      WaitFor-                   EnterCriticalSection
ReleaseMute   SetEvent                   LeaveCriticalSection
x
Closehandle   Closehandle                DeleteCriticalSection
   시그널 카운트
    ◦   카운트 > 0 : 세마포어 객체는 시그널
    ◦   카운트 == 0 : 세마포어 객체는 논 시그널
    ◦   카운트 < 0 : 음수는 나오지 않습니다
    ◦   카운트는 최대 카운트보다 작습니다

    ◦ 카운트에 의해 세마포어 객체가 시그널일 경우 스레드는
      논 시그널
    ◦ WaitFor-함수에 의해 카운트가 감소합니다
   초기 카운트 lInitialCount와 최대 카운트
    lMaximumCount는 설정 가능
   세마포어 카운트 증가
    ◦ 음수, 최대 카운트 이하값만 유효
   lpPreviousCount
    ◦ 이전 카운트 값
    ◦ NULL 가능
   프로세스 내부의 여러 스레드가 전역 자원 하나를
    두고 경쟁하는 경우 – 크리티컬 섹션
   서로 다른 프로세스의 여러 스레드에서 전역 자원
    하나를 두고 경쟁하는 경우 – 자동 이벤트, 뮤텍스
    ◦ 크리티컬 섹션에 비해 무겁습니다
   서로 다른 스레드가 같은 함수를 공유하며, 전역 자
    원을 두고 경쟁하는 경우 – 크리티컬 섹션, 뮤텍스
    ◦ 중복 소유를 인정하므로 교착 상태에 비교적 안전합니다
   비동기 I/O, 스레드 타이밍 동기화 – 수동 이벤트
   동기화 + 스레드 활동 수 제한 - 세마포어
   Windows의 기본 스케줄링 단위 : 스레드
    ◦ 프로세스는 그저 개념으로만 있습니다
   비선점형 멀티태스킹
    ◦ 프로세스가 CPU 자원을 독점하여 사용
    ◦ 프로세스가 자원을 서로 양보해야 합니다
   선점형 멀티태스킹
    ◦ 커널이 프로세스의 CPU 자원을 선점
   우선순위 주도의 라운드 로빈 스케줄링 시스템
    ◦ 단위 시간(n * 퀀텀)동안 스레드에게 CPU 할당
    ◦ 우선순위가 낮은 스레드는 실행중 대기할 수도 있습니다
   스레드가 실행할 준비가 됨(논 시그널)
   CPU를 모두 사용하거나 스레드가 종료되거나
    SwitchToThread() 호출로 시그널 됨
   Win32 API 호출로 우선 순위가 변경됨
    ◦ 실행중인 스레드의 우선 순위가 높아짐
   고정 우선순위 : 16~31, real-time
   가변 우선순위 : 1~15, 실행 중 임의로 변동
   0 페이지 : Windows에 0 페이지 스레드가 있습니다
    ◦ 0으로는 생성 불가


   기본 우선순위 : 초기 스레드 생성시
   실행 우선순위 : 스레드 수행중 임의로 변동
    ◦ 가변 우선순위 내에서 변동하며, 기본 우선순위도 가변
      우선순위인 경우
   기본 우선순위 결정 : 프로세스 우선순위 클래스 +
    스레드 우선순위(표는 임의의 약자입니다)
             IDLE   B_NOR   NOR   AB_NOR   HIGH   RT

    T_CRT    15      15     15      15     15     31

HIGHEST       6       8     10      12     15     26

    AB_NOR    5       7      9      11     14     25

     NOR      4       6      8      10     13     24

    B_NOR     3       5      7      9      12     23

    LOWEST    2       4      6      8      11     22

     IDLE     1       1      1      1       1     16
   device 드라이버가 사용하는 우선순위
    ◦ 17, 18, 19, 20, 21, 27, 28, 29, 30
   우선 순위에 상관없이 SetPriorityClass(),
    SetThreadPriority() 호출 가능
    ◦ 반영 안 될수도 있습니다
   클럭 단위(10ms)
   클럭 단위가 지날 때마다 3퀀텀 감소
   할당된 퀀텀이 0이 되는 경우 문맥 교환 발생
    ◦ 운영체제가 선점
   Windows 2000 커널 : 기본 6 퀀텀(20ms)
    ◦ 2000, 2003, XP, …
    ◦ 사용자의 요청에 대한 응답 속도 위주
   Windows Server 커널 : 기본 36퀀텀(120ms)
    ◦ 여러 클라이언트의 요청을 단일 주기에 처리하기 위함
스레드 생성과 초기화
      재초기화         초기화
                            준비 큐에 큐잉


 종료                 대기             준비
                  커널스택
       스레드가       교체방출
실행     객체 핸들                       실행을    선점
완료      대기          변환            위해 선택
                         커널스택
                         교체입력
 실행                               실행대기
         선점 또는 퀀텀시간 종료

             문맥 교환후 실행 시작
   스레드가 실행을 위해 기다리고 있는 상태로 준비
    상태의 스레드들은 실행 우선순위별 리스트로 구
    성되어 있다. 윈도우의 스케줄러는 실행할 스레드
    를 찾을 때, 준비 상태에 있는 스레드 리스트들 중
    에 가장 높은 실행 우선순위 리스트를 찾고 이 중
    에 맨 처음 스레드를 찾아 실행 대기 상태로 가져
    간다.
   윈도우의 스케줄러에 의해 다음에 실행되기 위해
    선택된 스레드의 상태가 실행 대기 상태이다. 스케
    줄러는 상황이 맞을 때 스레드에 대해 문맥 교환을
    수행하여 스레드를 실행 상태로 가져간다. 하나의
    코어에는 하나의 스레드만이 실행 대기 상태가 될
    수 있다. 어떤 스레드가 실행 대기 상태에 있다 하
    더라도 우선순위가 높은 스레드가 등장하면 실행
    대기 상태의 스레드는 다시 준비 상태로 간다.
   실행 대기 상태의 스레드에 대해 문맥 교환이 수행
    되면 스레드는 실행 상태로 들어가게 된다. 이렇게
    실행되고 있는 스레드는 더 높은 우선순위를 가진
    스레드에 의해 선점되거나, 할당된 퀀텀을 다 소모
    하거나, 종료되거나, 자발적으로 대기 상태에 들어
    갈 Eor까지 스레드를 계속 실행한다.
   스레드는 몇 가지 방법(동기화 대기, Sleep,
    Suspend, 메시지 대기)으로 대기 상태로 들어갈
    수 있다. 스레드가 대기 상태로 들어가는 가장 일
    반적인 경우는 스레드가 자발적으로 동기화 객체
    (event, semaphore, mutex, …)에 대해서
    WaitFor- 함수를 호출할 때 대기 상태로 들어간다.
    또 Windows는 스레드를 대신해서 대기 상태로 들
    어갈 수 있다(I/O). 스레드는 대기 상태가 끝났을
    때 준비 상태로 들어간다.
   스레드가 대기 상태에 있을 때 커널 스택이 메모리
    밖으로 페이징되어 나간다면 스레드는 변환 상태
    로 들어간다. 커널 스택이 다시 메모리상으로 돌아
    오면 스레드는 준비 상태로 들어간다.
   스레드가 실행을 마쳤을 때스레드는 종료 상태로
    간다. 커널은 스레드 객체를 다시 초기화하여 다시
    사용할 수 있다.
   스레드가 생성될 동안 Windows 시스템이 내부적
    으로 사용하는 스레드 상태이다.
스레드 생성과 초기화
      재초기화         초기화
                            준비 큐에 큐잉


 종료                 대기             준비
                  커널스택
       스레드가       교체방출
실행     객체 핸들                       실행을    선점
완료      대기          변환            위해 선택
                         커널스택
                         교체입력
 실행                               실행대기
         선점 또는 퀀텀시간 종료

             문맥 교환후 실행 시작
   실행 우선순위는 필요에 따라 변동
    ◦   I/O
    ◦   실행 이벤트 혹은 세마포어에 대한 대기가 끝난 후
    ◦   foreground 프로세스에 있는 스레드가 대기 작업을 수행한 후
    ◦   Windows 활동 때문에 UI 스레드가 깨어난 후
    ◦   준비 큐에 있는 스레드가 기아 상태에 빠질 때
   I/O
    ◦ 장치에서 IoCompleteRequest() 함수 호출
    ◦ 위의 함수에서 우선순위가 증가
    ◦ 퀀텀이 지날 때마다 1씩 감소
      기본 우선순위가 될 때까지 감소합니다


   이벤트/세마포어 대기 후
    ◦ 우선순위 1 증가
    ◦ 퀀텀이 지날 때 1 감소
   우선순위 2 증가
   퀀텀이 지날 때마다 1 감소
   앞의 경우를 포함하여 우선순위 4 증가
   퀀텀이 지날 때마다 1씩 감소
   빠른 응답을 위해 변동됩니다
   우선순위가 15가 됩니다
   할당받은 퀀텀이 2배로 증가
   퀀텀을 모두 사용한 경우 원래대로 복귀

                   우선순위 11


         우선순위 4
         스레드의      우선순위 7
         응답을 대기   오래 걸리는 작업
                     수행중
                              우선 순위에
    우선순위 4인                   밀려 대기중
    스레드 우선순                   (기아 상태)
                   우선순위 4
     위 증가

More Related Content

What's hot

비동기 파일 로딩
비동기 파일 로딩비동기 파일 로딩
비동기 파일 로딩Bongseok Cho
 
Free rtos seminar
Free rtos seminarFree rtos seminar
Free rtos seminarCho Daniel
 
Mastering ethereum(smart contract)
Mastering ethereum(smart contract)Mastering ethereum(smart contract)
Mastering ethereum(smart contract)제호 송
 
Javascript 조금 더 잘 알기
Javascript 조금 더 잘 알기Javascript 조금 더 잘 알기
Javascript 조금 더 잘 알기jongho jeong
 
파이썬 병렬프로그래밍
파이썬 병렬프로그래밍파이썬 병렬프로그래밍
파이썬 병렬프로그래밍Yong Joon Moon
 
Java 강의자료 ed11
Java 강의자료 ed11Java 강의자료 ed11
Java 강의자료 ed11hungrok
 
Realm.io for iOS
Realm.io for iOSRealm.io for iOS
Realm.io for iOSEunjoo Im
 
Windows via c++ part 1
Windows via c++ part 1Windows via c++ part 1
Windows via c++ part 1Shin heemin
 
Realm 코딩카페 - 이종찬
Realm   코딩카페 - 이종찬Realm   코딩카페 - 이종찬
Realm 코딩카페 - 이종찬Lee-Jong-Chan
 
Swift3 subscript inheritance initialization
Swift3 subscript inheritance initializationSwift3 subscript inheritance initialization
Swift3 subscript inheritance initializationEunjoo Im
 
Scope and Closure of JavaScript
Scope and Closure of JavaScript Scope and Closure of JavaScript
Scope and Closure of JavaScript Dahye Kim
 
Java programming pdf
Java programming pdfJava programming pdf
Java programming pdfJi Hoon Lee
 
Effective c++(chapter3,4)
Effective c++(chapter3,4)Effective c++(chapter3,4)
Effective c++(chapter3,4)문익 장
 
GCGC- CGCII 서버 엔진에 적용된 기술 (4) - Executing System
GCGC- CGCII 서버 엔진에 적용된 기술 (4) - Executing SystemGCGC- CGCII 서버 엔진에 적용된 기술 (4) - Executing System
GCGC- CGCII 서버 엔진에 적용된 기술 (4) - Executing System상현 조
 
스위프트, 코틀린과 모던언어의 특징 (Swift, Kotlin and Modern Languages)
스위프트, 코틀린과 모던언어의 특징 (Swift, Kotlin and Modern Languages)스위프트, 코틀린과 모던언어의 특징 (Swift, Kotlin and Modern Languages)
스위프트, 코틀린과 모던언어의 특징 (Swift, Kotlin and Modern Languages)Yongha Yoo
 

What's hot (20)

Java 8 고급 (2/6)
Java 8 고급 (2/6)Java 8 고급 (2/6)
Java 8 고급 (2/6)
 
Java 8 고급 (3/6)
Java 8 고급 (3/6)Java 8 고급 (3/6)
Java 8 고급 (3/6)
 
비동기 파일 로딩
비동기 파일 로딩비동기 파일 로딩
비동기 파일 로딩
 
Free rtos seminar
Free rtos seminarFree rtos seminar
Free rtos seminar
 
Mastering ethereum(smart contract)
Mastering ethereum(smart contract)Mastering ethereum(smart contract)
Mastering ethereum(smart contract)
 
Javascript 조금 더 잘 알기
Javascript 조금 더 잘 알기Javascript 조금 더 잘 알기
Javascript 조금 더 잘 알기
 
파이썬 병렬프로그래밍
파이썬 병렬프로그래밍파이썬 병렬프로그래밍
파이썬 병렬프로그래밍
 
Java 강의자료 ed11
Java 강의자료 ed11Java 강의자료 ed11
Java 강의자료 ed11
 
Realm.io for iOS
Realm.io for iOSRealm.io for iOS
Realm.io for iOS
 
Windows via c++ part 1
Windows via c++ part 1Windows via c++ part 1
Windows via c++ part 1
 
Anatomy of Realm
Anatomy of RealmAnatomy of Realm
Anatomy of Realm
 
Realm 코딩카페 - 이종찬
Realm   코딩카페 - 이종찬Realm   코딩카페 - 이종찬
Realm 코딩카페 - 이종찬
 
Swift3 subscript inheritance initialization
Swift3 subscript inheritance initializationSwift3 subscript inheritance initialization
Swift3 subscript inheritance initialization
 
120114 windows viacpp_03
120114 windows viacpp_03120114 windows viacpp_03
120114 windows viacpp_03
 
Scope and Closure of JavaScript
Scope and Closure of JavaScript Scope and Closure of JavaScript
Scope and Closure of JavaScript
 
Java programming pdf
Java programming pdfJava programming pdf
Java programming pdf
 
Effective c++(chapter3,4)
Effective c++(chapter3,4)Effective c++(chapter3,4)
Effective c++(chapter3,4)
 
tcp ip study
tcp ip studytcp ip study
tcp ip study
 
GCGC- CGCII 서버 엔진에 적용된 기술 (4) - Executing System
GCGC- CGCII 서버 엔진에 적용된 기술 (4) - Executing SystemGCGC- CGCII 서버 엔진에 적용된 기술 (4) - Executing System
GCGC- CGCII 서버 엔진에 적용된 기술 (4) - Executing System
 
스위프트, 코틀린과 모던언어의 특징 (Swift, Kotlin and Modern Languages)
스위프트, 코틀린과 모던언어의 특징 (Swift, Kotlin and Modern Languages)스위프트, 코틀린과 모던언어의 특징 (Swift, Kotlin and Modern Languages)
스위프트, 코틀린과 모던언어의 특징 (Swift, Kotlin and Modern Languages)
 

Similar to 동기화, 스케줄링

세션1. block chain as a platform
세션1. block chain as a platform세션1. block chain as a platform
세션1. block chain as a platformJay JH Park
 
스레드
스레드스레드
스레드xxbdxx
 
Windows via C/C++ 06 스레드의 기본
Windows via C/C++ 06 스레드의 기본Windows via C/C++ 06 스레드의 기본
Windows via C/C++ 06 스레드의 기본ssuser0c2478
 
Windows via c++ chapter6
Windows via c++   chapter6Windows via c++   chapter6
Windows via c++ chapter6Shin heemin
 
2017 tensor flow dev summit
2017 tensor flow dev summit2017 tensor flow dev summit
2017 tensor flow dev summitTae Young Lee
 
C# Game Server
C# Game ServerC# Game Server
C# Game Serverlactrious
 
스위프트 성능 이해하기
스위프트 성능 이해하기스위프트 성능 이해하기
스위프트 성능 이해하기Yongha Yoo
 
TenforFlow Internals
TenforFlow InternalsTenforFlow Internals
TenforFlow InternalsKiho Hong
 
7가지 동시성 모델 - 3장. 함수형 프로그래밍
7가지 동시성 모델 - 3장. 함수형 프로그래밍7가지 동시성 모델 - 3장. 함수형 프로그래밍
7가지 동시성 모델 - 3장. 함수형 프로그래밍Hyunsoo Jung
 
Java mentoring of samsung scsc 2
Java mentoring of samsung scsc   2Java mentoring of samsung scsc   2
Java mentoring of samsung scsc 2도현 김
 
Blockchain 2nd ethereum_core
Blockchain 2nd ethereum_coreBlockchain 2nd ethereum_core
Blockchain 2nd ethereum_coreihpark92
 
C++ Advanced 강의 4주차
 C++ Advanced 강의 4주차 C++ Advanced 강의 4주차
C++ Advanced 강의 4주차HyunJoon Park
 
NDC12_Lockless게임서버설계와구현
NDC12_Lockless게임서버설계와구현NDC12_Lockless게임서버설계와구현
NDC12_Lockless게임서버설계와구현noerror
 
[E6]2012. netty internals
[E6]2012. netty internals[E6]2012. netty internals
[E6]2012. netty internalsNAVER D2
 
[OpenTRS-001] Hotel California
[OpenTRS-001] Hotel California[OpenTRS-001] Hotel California
[OpenTRS-001] Hotel CaliforniaTheori
 

Similar to 동기화, 스케줄링 (20)

세션1. block chain as a platform
세션1. block chain as a platform세션1. block chain as a platform
세션1. block chain as a platform
 
스레드
스레드스레드
스레드
 
Windows via C/C++ 06 스레드의 기본
Windows via C/C++ 06 스레드의 기본Windows via C/C++ 06 스레드의 기본
Windows via C/C++ 06 스레드의 기본
 
Windows via c++ chapter6
Windows via c++   chapter6Windows via c++   chapter6
Windows via c++ chapter6
 
2017 tensor flow dev summit
2017 tensor flow dev summit2017 tensor flow dev summit
2017 tensor flow dev summit
 
강의자료 2
강의자료 2강의자료 2
강의자료 2
 
Gcd ppt
Gcd pptGcd ppt
Gcd ppt
 
C# Game Server
C# Game ServerC# Game Server
C# Game Server
 
스위프트 성능 이해하기
스위프트 성능 이해하기스위프트 성능 이해하기
스위프트 성능 이해하기
 
04 프로세스
04 프로세스04 프로세스
04 프로세스
 
TenforFlow Internals
TenforFlow InternalsTenforFlow Internals
TenforFlow Internals
 
7가지 동시성 모델 - 3장. 함수형 프로그래밍
7가지 동시성 모델 - 3장. 함수형 프로그래밍7가지 동시성 모델 - 3장. 함수형 프로그래밍
7가지 동시성 모델 - 3장. 함수형 프로그래밍
 
MutiCore 19-20
MutiCore 19-20MutiCore 19-20
MutiCore 19-20
 
Java mentoring of samsung scsc 2
Java mentoring of samsung scsc   2Java mentoring of samsung scsc   2
Java mentoring of samsung scsc 2
 
Blockchain 2nd ethereum_core
Blockchain 2nd ethereum_coreBlockchain 2nd ethereum_core
Blockchain 2nd ethereum_core
 
C++ Advanced 강의 4주차
 C++ Advanced 강의 4주차 C++ Advanced 강의 4주차
C++ Advanced 강의 4주차
 
NDC12_Lockless게임서버설계와구현
NDC12_Lockless게임서버설계와구현NDC12_Lockless게임서버설계와구현
NDC12_Lockless게임서버설계와구현
 
[E6]2012. netty internals
[E6]2012. netty internals[E6]2012. netty internals
[E6]2012. netty internals
 
[OpenTRS-001] Hotel California
[OpenTRS-001] Hotel California[OpenTRS-001] Hotel California
[OpenTRS-001] Hotel California
 
Node.js 기본
Node.js 기본Node.js 기본
Node.js 기본
 

동기화, 스케줄링

  • 2. TLS(Thread Local Storage)  스레드 동기화  커널 객체를 이용한 동기화  스레드 스케줄링
  • 3.
  • 4. 스레드 단위의 전역 변수  다른 스레드와 완전히 분리되는 변수  매개변수 대체 ◦ 매개변수의 개수를 무작정 늘리지 않습니다 ◦ 원형이 정해져있는 콜백 함수에서 참조 대용  TLS 지원 ◦ Win32 TLS, Compiler TLS, MFC TLS
  • 5. Thread 1 some() tls(value) tls(value) some() 호출 return some() tls(value) tls value1 tls value2 Thread 2 some() tls(value) tls(value) some() 호출 return
  • 6. 변수 함수 스레드 지역 변수 함수마다 독립 스레드마다 독립 정적 변수 모든 함수에서 공유 전체 스레드에서 공유 TLS 같은 스레드의 모든 함수에서 공유 스레드마다 독립
  • 7. Thread 1 Thread 2 0 INUSE 0 data 1 0 … 1 INUSE 1 … 1 data 1 2 FREE 2 … 2 … … … … … … … … … … … … … … … … … … … n … n … n … TLS Bit Flags TLS TLS n : Windows 95/NT = 64 Windows 98/ME = 80 Windows 2000/XP = 1088
  • 8. TLS Bit Flags 배열은 INUSE, FREE값 저장 ◦ 사용중, 사용가능 ◦ 실제 사용중인 것은 아니고 개념적인 것  초기 Bit Flags TLS 배열의 인덱스 할당 ◦ TlsAlloc()  TLS Bit Flags 배열의 비트 플래그 해제 ◦ TlsFree(dwTlsIndex)  TlsGetValue(index), TlsSetValue(index, value)
  • 9. TLS 배열에서 FREE인 인덱스 반환  TLS는 n * 4Byte 배열 n :Windows 98/ME = 80 Windows 95/NT = 64 ◦ sizeof(void *)? Windows 2000/XP = 1088  초기 TLS는 0으로 초기화되어있음
  • 10. 반환/설정 값은 적절한 자료형으로 캐스팅  자료형이 4Byte를 넘어갈 경우 Boxing ◦ TLS 배열에는 포인터 형태로 저장  접근하는 값은 다른 스레드와 상호 배타
  • 11. TLS Bit Flags를 INUSE에서 FREE로 설정  TLS Bit Flags 배열과 TLS 배열은 다릅니다 ◦ 배열 항목 개수가 동일합니다 ◦ TLS 배열은 스레드마다 할당
  • 12. 컴파일러에서 키워드 형태로 지원  __declspec(thread) 자료형 변수명 __declspec(thread) int k;  컴파일 단계에서 .tls 섹션으로 통합  스레드 생성 시 .tls에서 동적 할당 ◦ 컴파일러가 접근 코드를 삽입  선언만 다르고 나머지는 변수와 같습니다.
  • 13. TLS가 필요없는 스레드도 TLS 할당  컴파일러의 TLS 접근 코드 삽입 ◦ 추가 오버헤드 발생  LoadLibrary로 DLL을 로드하는 경우 사용 불가
  • 14. TLS를 사용하는 클래스는 CNoTrackObject 클래 스 상속  THREAD_LOCAL 매크로를 사용하여 선언  접근은 항상 -> 연산자 ◦ 연산자 오버로딩되어 있습니다 class CTls1 : public CNoTrackObjecct { public: int x, y; }; THREAD_LOCAL(CTls1, tls1); tls1->x = 10;
  • 15. 내부적으로 Win32 TLS를 사용  초기화는 내부에서 처리 ◦ 최초 접근시 초기화  CNoTrackObject, CThreadLocalObject, THREAD_LOCAL ◦ MSDN에 정식 등재된 클래스/매크로가 아님
  • 16. 스레드 안전 함수 ◦ 원자적 실행이 보장되는 함수  ANSI C의 스레드 안전하지 않은 함수 ◦ strtok, strerror, tmpnam, tmpfile, asctime, …  스레드 안전하게 보강된 라이브러리 사용 ◦ LibC.lib, LibCD.lib, LibCMt.lib, LibCMtD.lib, MSCVRt.lib, MSCVRtD.lib ◦ ~D.lib는 디버그 모드용 버전
  • 17.
  • 18. _threadstartex() ◦ 최초 TLS 관리 객체 초기화 ◦ 내부적으로 _endthreadex() 호출  _beginthreadex() ◦ 내부적으로 _threadstartex() 호출  _beginthreadex() 권장
  • 19.
  • 20. 원자적 연산 수행 ◦ 변수에 대한 접근이 자유롭지만 특정 순간에는 하나의 스 레드만 접근하여 연산 수행  문맥 교환 시점에 따라 원자적 수행이 불가능
  • 21. 전역(정적) 변수 자료형 동기화 방법 정수, 포인터 Interlocked- 함수, volatile 기타 동기화 객체
  • 22. 정수형 자료형에 대한 원자적인 연산 ◦ 프로그램에서 가장 많이 접근하는 자료형 ◦ int, long, void *, …  LONG InterlockedIncrement(LONG volatile *lpAddend)  LONG InterlockedDecrement(LONG volatile *lpAddend) ◦ lpAddend 매개변수를 1 증가 혹은 감소
  • 23. Long InterLockedExchangeAdd(LPLONG volatile Addend, LONG Value) ◦ Addend로 받은 주소에 Value 값만큼 증감  Long InterLockedExchange(LONG volatile *Target, LONG Value) ◦ Target으로 받은 주소에 Value 값 대입
  • 24. Long InterLockedCompareExchange (LONG volatile *Destination, LONG Exchange, LONG Comperand) ◦ Destination의 실제 값과 Comperand의 값이 같은 경우 Exchange를 Destination의 실제 값에 대입 ◦ if(*Destination == comperand) *Destination = Exchange;  PVOID InterlockedExchangePointer
  • 25. PVOID InterlockedExchangePointer(PVOID volatile *Target, PVOID Value) ◦ Target의 포인터 값을 Value 포인터로 변경  PVOID InterlockedCompareExchangePointer(PVOID volatile *Destination, PVOID Exchange, PVOID Comperand) ◦ Destination의 포인터 값이 Comperand값과 같다면 Destination의 포인터 값에 Exchange포인터로 변경
  • 26. 휘발성 변수를 선언할 때 사용 ◦ 코드 상에서 명시적으로 대입하는 것이 아닌 실제 CPU에 서 대입하게 하는 변수  컴파일러의 최적화 방지 ◦ 컴파일러는 최적화 과정에서 불필요한 연산을 하는 코드 를 감지, 삭제 ◦ volatile 키워드는 변수에 대한 연산 시 최적화에 의해 삭 제되는 코드를 삭제하지 못하게 막음
  • 27. 모든 전역 변수와 하드웨어와 매핑되는 변수에 사용  기계상으로 특정 주소에 위치한 장치에 대해 항상 값을 읽어올 때 사용  volatile을 생략한 경우 ◦ disassembly
  • 28. 모든 전역 변수와 하드웨어와 매핑되는 변수에 사용  기계상으로 특정 주소에 위치한 장치에 대해 항상 값을 읽어올 때 사용  volatile을 명시한 경우 ◦ disassembly
  • 29. 동기화 객체 특징 • 작고 빠르다 critical section • 소유 개념이 있고 중복 소유가 가능하다 • 프로세스 사이에 공유되지 않는다 • 크리티컬 섹션에 비해 무겁다 • 시그널, 논 시그널 개념이 있다 event • 자동과 수동 이벤트 개념이 있다 • 프로세스 사이에 공유될 수 있다 • 크리티컬 섹션에 비해 무겁다 semaphore • 시그널 카운트 개념이 있다 • 프로세스 사이에 공유될 수 있다 • 크리티컬 섹션에 비해 무겁다 mutex • 소유 개념이 있고 중복 소유가 가능하다 • 프로세스 사이에 공유될 수 있다
  • 30. CRITICAL_SECTION cs  LPCRITICAL_SECTION lpcs ◦ 크리티컬 섹션 객체와 그 포인터  void InitializeCriticalSection(lpcs) ◦ 크리티컬 섹션 객체 초기화  void DeleteCriticalSection(lpcs) ◦ 크리티컬 섹션 객체 해제
  • 31. void EnterCriticalSection(lpcs) ◦ 크티티컬 섹션 진입, 최대 30일 대기  BOOL TryEnterCriticalSection(lpcs) ◦ 진입 시도를 하여 성공하면 TRUE를 반환  void LeaveCriticalSection(lpcs) ◦ 크리티컬 섹션 탈출  중복 진입 가능 ◦ 탈출할 때에는 반드시 중복 진입한 수만큼 탈출
  • 32.
  • 33. 커널 객체는 프로세스간 동기화도 가능 ◦ OpenEvent(), OpenMutex(), OpenSemaphore()  인자에 이름을 넣습니다  이름은 각 객체에 대한 설명 때 나옵니다 ◦ 대신에 크고 무겁습니다  시그널 상태 ◦ 실행 대기중인 상태(잠자고 있습니다)  논 시그널 상태 ◦ 현재 실행중인 상태(깨어 있습니다)
  • 34. DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds) ◦ 커널 객체 hHandle에 대해 dwMilliseconds만큼 대기 ◦ 시그널에서 논 시그널이 될 때까지 대기
  • 35. 크기가 nCount인 lpHandles 배열의 핸들들을 dwMilliseconds만큼 대기  bWaitAll이 TRUE면 모든 스레드가 시그널 될 때까 지 대기
  • 36. 마지막 인자 dwMilliseconds를 통해 무제한 (INFINITE) 대기 가능  시그널 상태인지만 검사하는 경우 마지막 인자 dwMilliseconds에 0 대입  반환값 ◦ WAIT_OBJECT_0 : 시그널로 전환됨 ◦ WAIT_TIMEOUT : 시간 초과 ◦ WAIT_ABANDONED_0 : 기다리던 스레드가 종료됨  mutex 전용 ◦ WAIT_FAILED : 잘못된 hHandle 인자
  • 37. 가장 원시적인 커널 객체  자동 리셋 이벤트 ◦ 대기하던 스레드가 시그널 될 때 이벤트 객체가 자동으로 논 시그널 됨  수동 리셋 이벤트 ◦ 대기하던 스레드가 시그널 되더라도 이벤트 객체는 유지됨 ◦ BOOL ResetEvent(HANDLE hEvent)로 이벤트 객체를 논 시그널로 전환
  • 38. // 생성된 이벤트 핸들  lpEventAttributes : 속성  bManualReset : 자동/수동  bInitialState : 시그널/논 시그널  lpName : 이벤트 이름
  • 39. BOOL SetEvent(HANDLE hEvent)  BOOL ResetEvent(HANDLE hEvent)  hEvent 이벤트를 Set(시그널), Reset(논 시그널)
  • 40. 자동 이벤트와 크리티컬 섹션을 비교합니다 자동 이벤트 크리티컬 섹션 CreateEvent(NULL, FALSE, TRUE, InitializeCriticalSection NULL) WaitFor- EnterCriticalSection SetEvent LeaveCriticalSection Closehandle DeleteCriticalSection
  • 41. WaitForMultipleObject와 동일합니다  마지막 인자 dwWakeMask ◦ QS_ALLINPUT을 대입하면 메세지 큐의 모든 이벤트 대기
  • 42. 뮤텍스 획득 = 논 시그널과 유사  뮤텍스 해제 = 시그널과 유사  두번째 인자 bInitalOwner가 TRUE면 생성 직후 뮤 텍스를 획득
  • 43. BOOL ReleaseMutex(HANDLE hMutex) ◦ 뮤텍스 hMutex를 해제  WaitFor-함수의 반환값 WAIT_ABANDONED_0 ◦ 뮤텍스를 소유하던 WAIT_ABANDONED_0(배열상의 +n 번째) 스레드가 종료되어 논 시그널 상태가 된 경우
  • 44. 뮤텍스와 이벤트, 크리티컬 섹션을 비교합니다 뮤텍스 자동 이벤트 크리티컬 섹션 CreateMutex CreateEvent(NULL, FALSE, InitializeCriticalSection TRUE, NULL) WaitFor- WaitFor- EnterCriticalSection ReleaseMute SetEvent LeaveCriticalSection x Closehandle Closehandle DeleteCriticalSection
  • 45. 시그널 카운트 ◦ 카운트 > 0 : 세마포어 객체는 시그널 ◦ 카운트 == 0 : 세마포어 객체는 논 시그널 ◦ 카운트 < 0 : 음수는 나오지 않습니다 ◦ 카운트는 최대 카운트보다 작습니다 ◦ 카운트에 의해 세마포어 객체가 시그널일 경우 스레드는 논 시그널 ◦ WaitFor-함수에 의해 카운트가 감소합니다
  • 46. 초기 카운트 lInitialCount와 최대 카운트 lMaximumCount는 설정 가능
  • 47. 세마포어 카운트 증가 ◦ 음수, 최대 카운트 이하값만 유효  lpPreviousCount ◦ 이전 카운트 값 ◦ NULL 가능
  • 48. 프로세스 내부의 여러 스레드가 전역 자원 하나를 두고 경쟁하는 경우 – 크리티컬 섹션  서로 다른 프로세스의 여러 스레드에서 전역 자원 하나를 두고 경쟁하는 경우 – 자동 이벤트, 뮤텍스 ◦ 크리티컬 섹션에 비해 무겁습니다  서로 다른 스레드가 같은 함수를 공유하며, 전역 자 원을 두고 경쟁하는 경우 – 크리티컬 섹션, 뮤텍스 ◦ 중복 소유를 인정하므로 교착 상태에 비교적 안전합니다  비동기 I/O, 스레드 타이밍 동기화 – 수동 이벤트  동기화 + 스레드 활동 수 제한 - 세마포어
  • 49.
  • 50. Windows의 기본 스케줄링 단위 : 스레드 ◦ 프로세스는 그저 개념으로만 있습니다  비선점형 멀티태스킹 ◦ 프로세스가 CPU 자원을 독점하여 사용 ◦ 프로세스가 자원을 서로 양보해야 합니다  선점형 멀티태스킹 ◦ 커널이 프로세스의 CPU 자원을 선점  우선순위 주도의 라운드 로빈 스케줄링 시스템 ◦ 단위 시간(n * 퀀텀)동안 스레드에게 CPU 할당 ◦ 우선순위가 낮은 스레드는 실행중 대기할 수도 있습니다
  • 51. 스레드가 실행할 준비가 됨(논 시그널)  CPU를 모두 사용하거나 스레드가 종료되거나 SwitchToThread() 호출로 시그널 됨  Win32 API 호출로 우선 순위가 변경됨 ◦ 실행중인 스레드의 우선 순위가 높아짐
  • 52. 고정 우선순위 : 16~31, real-time  가변 우선순위 : 1~15, 실행 중 임의로 변동  0 페이지 : Windows에 0 페이지 스레드가 있습니다 ◦ 0으로는 생성 불가  기본 우선순위 : 초기 스레드 생성시  실행 우선순위 : 스레드 수행중 임의로 변동 ◦ 가변 우선순위 내에서 변동하며, 기본 우선순위도 가변 우선순위인 경우
  • 53. 기본 우선순위 결정 : 프로세스 우선순위 클래스 + 스레드 우선순위(표는 임의의 약자입니다) IDLE B_NOR NOR AB_NOR HIGH RT T_CRT 15 15 15 15 15 31 HIGHEST 6 8 10 12 15 26 AB_NOR 5 7 9 11 14 25 NOR 4 6 8 10 13 24 B_NOR 3 5 7 9 12 23 LOWEST 2 4 6 8 11 22 IDLE 1 1 1 1 1 16
  • 54. device 드라이버가 사용하는 우선순위 ◦ 17, 18, 19, 20, 21, 27, 28, 29, 30  우선 순위에 상관없이 SetPriorityClass(), SetThreadPriority() 호출 가능 ◦ 반영 안 될수도 있습니다
  • 55. 클럭 단위(10ms)  클럭 단위가 지날 때마다 3퀀텀 감소  할당된 퀀텀이 0이 되는 경우 문맥 교환 발생 ◦ 운영체제가 선점  Windows 2000 커널 : 기본 6 퀀텀(20ms) ◦ 2000, 2003, XP, … ◦ 사용자의 요청에 대한 응답 속도 위주  Windows Server 커널 : 기본 36퀀텀(120ms) ◦ 여러 클라이언트의 요청을 단일 주기에 처리하기 위함
  • 56. 스레드 생성과 초기화 재초기화 초기화 준비 큐에 큐잉 종료 대기 준비 커널스택 스레드가 교체방출 실행 객체 핸들 실행을 선점 완료 대기 변환 위해 선택 커널스택 교체입력 실행 실행대기 선점 또는 퀀텀시간 종료 문맥 교환후 실행 시작
  • 57. 스레드가 실행을 위해 기다리고 있는 상태로 준비 상태의 스레드들은 실행 우선순위별 리스트로 구 성되어 있다. 윈도우의 스케줄러는 실행할 스레드 를 찾을 때, 준비 상태에 있는 스레드 리스트들 중 에 가장 높은 실행 우선순위 리스트를 찾고 이 중 에 맨 처음 스레드를 찾아 실행 대기 상태로 가져 간다.
  • 58. 윈도우의 스케줄러에 의해 다음에 실행되기 위해 선택된 스레드의 상태가 실행 대기 상태이다. 스케 줄러는 상황이 맞을 때 스레드에 대해 문맥 교환을 수행하여 스레드를 실행 상태로 가져간다. 하나의 코어에는 하나의 스레드만이 실행 대기 상태가 될 수 있다. 어떤 스레드가 실행 대기 상태에 있다 하 더라도 우선순위가 높은 스레드가 등장하면 실행 대기 상태의 스레드는 다시 준비 상태로 간다.
  • 59. 실행 대기 상태의 스레드에 대해 문맥 교환이 수행 되면 스레드는 실행 상태로 들어가게 된다. 이렇게 실행되고 있는 스레드는 더 높은 우선순위를 가진 스레드에 의해 선점되거나, 할당된 퀀텀을 다 소모 하거나, 종료되거나, 자발적으로 대기 상태에 들어 갈 Eor까지 스레드를 계속 실행한다.
  • 60. 스레드는 몇 가지 방법(동기화 대기, Sleep, Suspend, 메시지 대기)으로 대기 상태로 들어갈 수 있다. 스레드가 대기 상태로 들어가는 가장 일 반적인 경우는 스레드가 자발적으로 동기화 객체 (event, semaphore, mutex, …)에 대해서 WaitFor- 함수를 호출할 때 대기 상태로 들어간다. 또 Windows는 스레드를 대신해서 대기 상태로 들 어갈 수 있다(I/O). 스레드는 대기 상태가 끝났을 때 준비 상태로 들어간다.
  • 61. 스레드가 대기 상태에 있을 때 커널 스택이 메모리 밖으로 페이징되어 나간다면 스레드는 변환 상태 로 들어간다. 커널 스택이 다시 메모리상으로 돌아 오면 스레드는 준비 상태로 들어간다.
  • 62. 스레드가 실행을 마쳤을 때스레드는 종료 상태로 간다. 커널은 스레드 객체를 다시 초기화하여 다시 사용할 수 있다.  스레드가 생성될 동안 Windows 시스템이 내부적 으로 사용하는 스레드 상태이다.
  • 63. 스레드 생성과 초기화 재초기화 초기화 준비 큐에 큐잉 종료 대기 준비 커널스택 스레드가 교체방출 실행 객체 핸들 실행을 선점 완료 대기 변환 위해 선택 커널스택 교체입력 실행 실행대기 선점 또는 퀀텀시간 종료 문맥 교환후 실행 시작
  • 64. 실행 우선순위는 필요에 따라 변동 ◦ I/O ◦ 실행 이벤트 혹은 세마포어에 대한 대기가 끝난 후 ◦ foreground 프로세스에 있는 스레드가 대기 작업을 수행한 후 ◦ Windows 활동 때문에 UI 스레드가 깨어난 후 ◦ 준비 큐에 있는 스레드가 기아 상태에 빠질 때
  • 65. I/O ◦ 장치에서 IoCompleteRequest() 함수 호출 ◦ 위의 함수에서 우선순위가 증가 ◦ 퀀텀이 지날 때마다 1씩 감소  기본 우선순위가 될 때까지 감소합니다  이벤트/세마포어 대기 후 ◦ 우선순위 1 증가 ◦ 퀀텀이 지날 때 1 감소
  • 66. 우선순위 2 증가  퀀텀이 지날 때마다 1 감소
  • 67. 앞의 경우를 포함하여 우선순위 4 증가  퀀텀이 지날 때마다 1씩 감소  빠른 응답을 위해 변동됩니다
  • 68. 우선순위가 15가 됩니다  할당받은 퀀텀이 2배로 증가  퀀텀을 모두 사용한 경우 원래대로 복귀 우선순위 11 우선순위 4 스레드의 우선순위 7 응답을 대기 오래 걸리는 작업 수행중 우선 순위에 우선순위 4인 밀려 대기중 스레드 우선순 (기아 상태) 우선순위 4 위 증가