SlideShare a Scribd company logo
1 of 48
유저 모드에서의 스레드 동기화
 Thread Synchronization in User Mode




                                           아꿈사
                     http://cafe.naver.com/architect1

                                           최성기
                                florist.sk@gmail.com
1. 원자적 접근 : Interlocked 함수들
2. 캐시 라인
3. 고급 스레드 동기화 기법
4. 크리티컬 섹션
5. 슬림 리더-라이터 락
6. 조건변수
1. 원자적 접근 : Interlocked 함수들
2. 캐시 라인
3. 고급 스레드 동기화 기법
4. 크리티컬 섹션
5. 슬림 리더-라이터 락
6. 조건변수
어떤 스레드가 특정 리소스를 접근할 때
다른 스레드는 동일 시간에 동일 리소스에
접근할 수 없는 것을 말한다.
a thread's ability to access a resource with the guarantee
that no other thread will access that same resource
at the same time.
int g_x = 10;
                           스레드 1   스레드 2
 void func()
 {
     assert( g_x != 0 );
     ...
     g_x = 0;
     ...
     g_x = 10;
 }


병렬실행을 고려하지 않은 코드가 동시에 실행되면서
공유자원의 값이 예측 불가능한 것도 문제긴 하지만
int g_x = 0;
                           스레드 1   스레드 2
void func()
{
    g_x++;
}



                  = 원자적으로 보이는 명령
코드상으로는 괜찮아 보이는 경우에도


병렬 실행시 이상해 지는 경우가 있다.
              = 원자적이지 않다는 소리
C++ 코드      x86 어셈블리 코드

              MOV EAX, [g_x]
   g_x++;     INC EAX
              MOV [g_x], EAX




C++에서 한 줄의 명령어로 표현 되더라도
컴파일된 어셈블리 코드는 여러 단계로 나뉘어져
동시에 실행됨을 보장할 수 없는 경우가 있다.
int g_x = 0;
                     스레드 1   스레드 2
void func()
{
    // g_x++;
    MOV EAX, [g_x]
    INC EAX
    MOV [g_x], EAX
}




   이렇게 풀어서 써보면 처음과 비슷해짐.
int i = 0;
int j = 20;         vs2010, x86, debug

i = i + 1;    mov          eax,dword ptr [i]
              add          eax,1
i++;          mov          dword ptr [i],eax

++i;          mov          eax,dword ptr [j]
              mov          dword ptr [i],eax
i = j;
              mov          dword ptr [i],15h
i = 21;




다음 중 원자적인 연산은?
int i = 0;
    int j = 20;            vs2010, x86,   release (/O2)
    i = i + 1;
                    inc      dword ptr [ebp-4]    ??
    i++;

    ++i;            mov        eax,dword ptr [ebp-8]
                    push       esi
    i = j;
                    mov        dword ptr [ebp-4],15h
    i = 21;


x86 명령어셋은 메모리값을 1증가시키는 단일명령어 inc도 지원

하나의 기계어라도 CISC 명령어가 내부 파이프라인으로 들어가면
결국 레지스터로 load – add – store하는
마이크로 명령어로 분해될 수 있음을 유의해야 한다.
                                                   337p.
int g_x = 0;

    void func()
    {
        lock();
        g_x++;
        unlock();
    }


아니 그럼 멀티 스레드 에서는
고작 정수형 변수 하나 건드릴 때에도
매번 락을 걸어야 하나요?
이런 절차로 어린 코더가 니르고저 할빼이셔도
비로서 제 뜻을 시러 펴디 못할 노미 하니라.

InterlockedExchangeAdd( 변수주소, 값 );
InterlockedExchangeAdd64( 변수주소, 값 );
InterlockedExchange( 변수주소, 값 );
InterlockedExchange64( 변수주소, 값 );
InterlockedExchangePointer( 변수주소, 값 );

InterlockedIncrement( 변수주소 );
InterlockedDecrement( 변수주소 );
…
int g_x = 0;    int g_x = 0;

void func()     void func()
{               {
    lock();
    g_x++;          InterlockedExchangeAdd( &g_x, 1 );
    unlock();
}               }



정수형 변수의 값을 원자적으로 다뤄야 할 때
인터락 함수를 이용하면 된다.
     빠르게 수행됨 (50사이클 미만)
     유저모드 – 커널모드의 전환을 일으키지 않음.
// 공유 리소스의 사용 여부를 나타내는 전역변수
BOOL g_fResourceInUse = FALSE; ...
void Func1()
{
    // 리소스의 접근을 기다림
    while (InterlockedExchange(&g_fResourceInUse, TRUE) == TRUE)
          Sleep(0);
    // 리소스에 접근함
    ...
    // 리소스에 더 이상 접근할 필요가 없음
    InterlockedExchange(&g_fResourceInUse, FALSE);
}




InterlockedExchange는 특별히 스핀락spinlock을
구현해야 하는 경우에 유용하게 사용될 수 있다.
값의 비교와 변경을 원자적으로 해주는 연산.
멀티스레드 프로그래밍에 필수적인 뮤텍스, 세마포등의
동기화 객체synchronization object를 만드는 데 쓰인다.



InterlockedCompareExchange( 변수주소, 변경값, 비교값 );
InterlockedCompareExchange64( … );
InterlockedCompareExchangePointer( … );
void mutex_lock( int* lock_var )
{
    while( InterlockedCompareExchange( lock_var, 0, 1 ) );
}


void mutex_unlock( int* lock_var )
{
    *lock_var = 0;
}



    CAS 연산만을 가지고 구현한
    lock / unlock 함수.
                                               338p.
스레드 1                  스레드 2

                      x == A
                                               x = B

                                               x = A
                      x == A


CAS 연산이 다른 스레드의 접근을 감지하지 못하는 현상.
Interlocked Singly Linked List 사용시 주의점. - http://devnote.tistory.com/207
1. 원자적 접근 : Interlocked 함수들
2. 캐시 라인
3. 고급 스레드 동기화 기법
4. 크리티컬 섹션
5. 슬림 리더-라이터 락
6. 조건변수
정말 최적화된 프로그램을 작성하고 싶다면
캐시 미스(cache miss)가 적게 일어나도록 신경써야 한다.




                    http://goo.gl/7j5yP


인접한 메모리 데이터는 같은 캐시라인으로 구성되어
코어마다 분리된 캐시에 적재되기 때문.
1. CPU1이 메모리 1000번지 값을 읽는다.
                                  234p.
  •   값을 읽어 캐시에 보관

2. CPU2도 메모리 1000번지 값을 읽는다.
  •   값을 읽어 캐시에 보관

3. CPU1이 메모리 1000번지 값을 변경한다.
  •   캐시의 값 변경. 아직 RAM에 쓰기 전.

4. CPU2가 다시 1000번지 값을 읽는다.
  •   자신의 캐시에 값이 있지만 최신 내용이 아님.
      cache coherence miss 발생.
1. 읽기 전용의 데이터와 읽고쓰는 데이터를 분리
2. 동일 시간에 접근하는 데이터를 묶어서 구성
3. CPU의 캐시라인 크기를 알아내서,
   데이터 정렬을 캐시라인 크기별로 구성.

 캐시라인 크기 알아내기 : GetLogicalProcessorInformation()
  - http://goo.gl/MVZPH
 구조체 정렬 임의로 조절하기 : __declspec(align(#))
  - http://pmguda.com/378
  - http://goo.gl/w8SyL
1. 원자적 접근 : Interlocked 함수들
2. 캐시 라인
3. 고급 스레드 동기화 기법
4. 크리티컬 섹션
5. 슬림 리더-라이터 락        스핀락 vs 대기모드
                      전역변수 스핀락(?)
6. 조건변수               volatile 키워드.
1. 원자적 접근 : Interlocked 함수들
2. 캐시 라인
3. 고급 스레드 동기화 기법
4. 크리티컬 섹션
5. 슬림 리더-라이터 락
6. 조건변수
공유 리소스에 대해 배타적으로 접근해야 하는
작은 코드의 집합을 의미한다.

공유 리소스를 다루는 여러 줄의 코드를
원자적으로 수행하기 위한 방법이다.
인터락 함수로 동기화를 해결할 수 없다면
크리티컬 섹션을 사용하라.

장점
• 사용이 쉽고 내부적으로 인터락 함수를 사용해 빠르다.

단점
• 서로 다른 프로세스의 스레드 간에는 사용할 수 없다.
int g_x = 0;

void func()
{
    EnterCriticalSection( &g_cs );
    for( int i = 0; i < 1000; i++ )
    {                                 Critical
        g_x += i;                     Section
    }
    LeaveCriticalSection( &g_cs );
}


    크리티컬 섹션으로 둘러쌓인 코드는
    동시에 하나의 스레드밖에 진입할 수 없다.
1. 이미 Critical Section에 진입한 스레드가
   다시 Enter 해도 괜찮다.
  단, Enter 횟수만큼 Leave 해주어야 한다.


2. 다른 스레드가 진입해 있다면 뒤에 호출한 스레드는
   이벤트 커널 오브젝트를 이용해 대기 상태로 전환.
스레드를 절대 대기 상태로 진입시키지 않는다.


호출한 스레드가 진입해 성공했다면 TRUE 반환,
다른 스레드가 이미 진입해서 실패했다면 FALSE 반환.
스레드가 스핀락spinlock을 돌면서 대기하면
  CPU 시간을 소모하면서 대기하는 방식.
  대기 시간이 길어지면 CPU자원의 낭비가 된다.


스레드가 운영체제의 대기상태wait state로 전환되면
  CPU 자원을 낭비하지 않는다.
  대기 시간이 길어질 수록 효율적인 대기방식.
스레드가 스핀락spinlock을 돌면서 대기하면
  CPU 시간을 소모하면서 대기하는 방식.
  대기 시간이 길어지면 CPU자원의 낭비가 된다.
  대기 시간이 짧다면 바로 자원 획득이 가능.

스레드가 운영체제의 대기상태wait state로 전환되면
  CPU 자원을 낭비하지 않는다.
  대기 시간이 길어질 수록 효율적인 대기방식.
  커널모드로 전환되어야 함.
   대기 시간이 짧을 때는 오히려 상당한 CPU 낭비.
그래서 이 둘을 합쳐,
EnterCriticalSection이 호출되면

1. 일정 횟수 스핀락으로 루프를 돌아 대기.
2. 지정된 횟수 동안 리소스 획득에 실패했다면
   커널 모드로 전환해 스레드를 대기 상태로 전환.

하는 방식으로 사용할 수 있게 되어있다.
크리티컬 섹션에 스핀락을 사용하기 위한 초기화

 InitializeCriticalSection(…)
 BOOL InitializeCriticalSectionAndSpinCount(
     PCRITICAL_SECTION pcs,
     DWORD dwSpinCount );


스핀 횟수를 중간에 변경
 VOID SetCriticalSectionSpinCount(
     PCRITICAL_SECTION pcs,
     DWORD dwSpinCount );
주의 :
InitializeCriticalSection 는   가끔   예외를 던진다.

 시스템 가용메모리가 모자라 블록 할당이 실패하면
 STATUS_NO_MEMORY 예외가 발생.
 초기 설계시에 리턴값을 VOID로 해버려서.. 방법이 없다능..


 ..AndSpinCount 함수는 동일 상황에 FALSE를 리턴한다.

          해결책 :
          1. exception handling 처리를 하거나
          2. …AndSpinCount 함수를 쓸 것.
주의 :
EnterCriticalSection 도   가끔   예외를 던진다.

시스템 메모리가 모자라면 이벤트 객체 생성에 실패하면서
EXCEPTION_INVALID_HANDLE 예외가 발생.
예외가 생뚱맞아서 막상 해당 상황을 디버깅 하려면 헤맬 수 있다.


단, XP 이전의 운영체제에서만 예외가 발생한다.
XP부터는 키 이벤트key event라는 객체가 생겨서 이를 사용함.

       해결책 :
       1. XP 이전 OS를 버리세요.
       2. 스핀카운트 최상위비트를 설정해 초기화.
          초기화 시점에 미리 이벤트 객체가 생성됨.
책에서는 CRITICAL_SECTION 구조체의 변수 값은
알 필요 없다고 하고 설명도 없는데




데드락을 디버깅하는 데 많은 도움이 됩니다.
MSDN 매거진 자료 링크 : http://goo.gl/OGY0M
1. 원자적 접근 : Interlocked 함수들
2. 캐시 라인
3. 고급 스레드 동기화 기법
4. 크리티컬 섹션
5. 슬림 리더-라이터 락
6. 조건변수
Read/Write lock은 고전적인 동기화 기법의 하나.
                   http://devnote.tistory.com/177

 Write 작업은 한 번에 하나밖에 실행될 수 없지만
 Read 작업은 동시에 여러 개가 실행될 수 있게 처리.




                              http://goo.gl/u9TUN

이런 동기화 방식을 Windows Vista / 2008 Server부터
Win32 API 자체적으로 지원한다.
사용 방식은 CriticalSection과 매우 흡사하다.

동작        CriticalSection           SRWLock
초기화       InitializeCriticalSection InitializeSRWLock
릴리즈       DeleteCriticalSection     없음
Lock      EnterCriticalSection      AcquireSRWLockExclusive (Write)
                                    ActuireSRWLockShared (Read)
Unlock    DeleteCriticalSection     ReleaseSRWLockExclusive (Write)
                                    ReleaseSRWLockShared (Read)
TryLock   TryEnterCriticalSection   TryAcquireSRWLockExclusive (Write)
                                    TryAcquireSRWLockShared (Read)
책에는 TryEnter(Shared/Exclusive)SRWLock 함수가
없다고 나오지만 현재는 추가되었음(308p).

이전의 API들보다 늦게 추가되었으며
Windows 7 / Server 2008 R2 이상에서만 지원된다.
스레드/   volatile   volatile   Interlocked   크리티컬   SRWLock   SRWLock     뮤텍스
밀리초    변수 읽기      변수 쓰기      Increment     섹션     Shared    Exclusive

1      8          8          35            66     66        67          1060
2      8          76         153           268    134       148         11082
4      9          145        361           768    244       307         23785



    벤치마크에 사용된 코드를 보면
    크리티컬 섹션은 스핀락을 사용하지 않은 경우.

    - 크리티컬 섹션과 뮤텍스 모두 커널모드로 전환이 발생하나
      뮤텍스는 커널모드 전환비용 이상의 코스트가 발생한다.
1. 원자적 접근 : Interlocked 함수들
2. 캐시 라인
3. 고급 스레드 동기화 기법
4. 크리티컬 섹션
5. 슬림 리더-라이터 락
6. 조건변수
http://goo.gl/T8uBM




Slim Reader/Writer Lock과 함께
Vista / 2008 Server부터 지원.

조건변수condition variable 역시
병렬처리 이론적으로는 예전부터 정립되어 있는 개념이며

자바나 C#의 Monitor 클래스가 이를 구현하고 있고
POSIX 스레드에도 들어있던 기능.
boost::thread에도 구현되어 있다.
ACE에도 있는 것 같..지만 제가 ACE를 제대로 본 적이 없네요..
조건변수를 사용하면 스레드가 리소스에 대한 락을
해제하고 SleepConditionVariable*함수에서 지정한
상태가 될 때까지 스레드를 블로킹 해준다.

   BOOL SleepConditionVariableCS(
     PCONDITION_VARIABLE pConditionVariable,
     PCRITICAL_SECTION pCriticalSection,
     DWORD dwMilliseconds );

   BOOL SleepConditionVariableSRW(
     PCONDITION_VARIABLE pConditionVariable,
     PSRWLOCK pSRWLock,
     DWORD dwMilliseconds,
     ULONG Flags ); // 읽기, 쓰기 구분 플래그
CONDITION_VARIABLE cond;
InitializeConditionVariable( &cond );

EnterCriticalSection( &cs );
…
while( !프로세스 종료상황 )
{
  if( 지금 작업 가능한 상황 )
  {
    … 씐나게 작업을 한다.
  }
  else // 작업 불가능.
  {
    SleepConditionVariableCS( &cond, &cs, INFINITE );
  }
}

LeaveCriticalSection( &cs );
조건변수를 이용해 Sleep한 스레드를 깨워야 할 때는
Wake*ConditionVariable 함수로
하나 혹은 모든 스레드를 wake 시킬 수 있다.

  VOID WakeConditionVariable(
    PCONDITION_VARIABLE pConditionVariable );

  VOID WakeAllConditionVariable(
    PCONDITION_VARIABLE pConditionVariable );
1. 원자적으로 관리되어야 하는 오브젝트 집합당
   하나의 락만을 사용하라.

2. 다수의 논리적 리소스에 동시에 접근하려면
   다수의 리소스 락을 원자적으로 설정해야 한다.
       스레드1               스레드2
  Enter..( &cs1 );   Enter..( &cs2 );
  Enter..( &cs2 );   Enter..( &cs1 );


3. 락을 장시간 점유하지 말 것.
  장시간 작업이 필요할 땐 리소스를 복사해서 사용
1. 원자적 접근 : Interlocked 함수들
2. 캐시 라인
3. 고급 스레드 동기화 기법
4. 크리티컬 섹션
5. 슬림 리더-라이터 락
6. 조건변수
유저 모드에서의 스레드 동기화
 Thread Synchronization in User Mode




            끝♥

More Related Content

What's hot

시즌 2: 멀티쓰레드 프로그래밍이 왜이리 힘드나요?
시즌 2: 멀티쓰레드 프로그래밍이 왜이리 힘드나요?시즌 2: 멀티쓰레드 프로그래밍이 왜이리 힘드나요?
시즌 2: 멀티쓰레드 프로그래밍이 왜이리 힘드나요?내훈 정
 
중앙 서버 없는 게임 로직
중앙 서버 없는 게임 로직중앙 서버 없는 게임 로직
중앙 서버 없는 게임 로직Hoyoung Choi
 
Multiplayer Game Sync Techniques through CAP theorem
Multiplayer Game Sync Techniques through CAP theoremMultiplayer Game Sync Techniques through CAP theorem
Multiplayer Game Sync Techniques through CAP theoremSeungmo Koo
 
LockFree Algorithm
LockFree AlgorithmLockFree Algorithm
LockFree AlgorithmMerry Merry
 
MMOG Server-Side 충돌 및 이동처리 설계와 구현
MMOG Server-Side 충돌 및 이동처리 설계와 구현MMOG Server-Side 충돌 및 이동처리 설계와 구현
MMOG Server-Side 충돌 및 이동처리 설계와 구현YEONG-CHEON YOU
 
Ndc2014 시즌 2 : 멀티쓰레드 프로그래밍이 왜 이리 힘드나요? (Lock-free에서 Transactional Memory까지)
Ndc2014 시즌 2 : 멀티쓰레드 프로그래밍이  왜 이리 힘드나요?  (Lock-free에서 Transactional Memory까지)Ndc2014 시즌 2 : 멀티쓰레드 프로그래밍이  왜 이리 힘드나요?  (Lock-free에서 Transactional Memory까지)
Ndc2014 시즌 2 : 멀티쓰레드 프로그래밍이 왜 이리 힘드나요? (Lock-free에서 Transactional Memory까지)내훈 정
 
Tcp ip & io model
Tcp ip & io modelTcp ip & io model
Tcp ip & io modelNam Hyeonuk
 
Akka.NET 으로 만드는 온라인 게임 서버 (NDC2016)
Akka.NET 으로 만드는 온라인 게임 서버 (NDC2016)Akka.NET 으로 만드는 온라인 게임 서버 (NDC2016)
Akka.NET 으로 만드는 온라인 게임 서버 (NDC2016)Esun Kim
 
게임프로젝트에 적용하는 GPGPU
게임프로젝트에 적용하는 GPGPU게임프로젝트에 적용하는 GPGPU
게임프로젝트에 적용하는 GPGPUYEONG-CHEON YOU
 
[야생의 땅: 듀랑고] 서버 아키텍처 Vol. 2 (자막)
[야생의 땅: 듀랑고] 서버 아키텍처 Vol. 2 (자막)[야생의 땅: 듀랑고] 서버 아키텍처 Vol. 2 (자막)
[야생의 땅: 듀랑고] 서버 아키텍처 Vol. 2 (자막)Heungsub Lee
 
게임서버프로그래밍 #1 - IOCP
게임서버프로그래밍 #1 - IOCP게임서버프로그래밍 #1 - IOCP
게임서버프로그래밍 #1 - IOCPSeungmo Koo
 
게임서버프로그래밍 #2 - IOCP Adv
게임서버프로그래밍 #2 - IOCP Adv게임서버프로그래밍 #2 - IOCP Adv
게임서버프로그래밍 #2 - IOCP AdvSeungmo Koo
 
홍성우, 게임 서버의 목차 - 시작부터 출시까지, NDC2019
홍성우, 게임 서버의 목차 - 시작부터 출시까지, NDC2019홍성우, 게임 서버의 목차 - 시작부터 출시까지, NDC2019
홍성우, 게임 서버의 목차 - 시작부터 출시까지, NDC2019devCAT Studio, NEXON
 
임태현, MMO 서버 개발 포스트 모템, NDC2012
임태현, MMO 서버 개발 포스트 모템, NDC2012임태현, MMO 서버 개발 포스트 모템, NDC2012
임태현, MMO 서버 개발 포스트 모템, NDC2012devCAT Studio, NEXON
 
게임서버프로그래밍 #4 - 멀티스레드 프로그래밍
게임서버프로그래밍 #4 - 멀티스레드 프로그래밍게임서버프로그래밍 #4 - 멀티스레드 프로그래밍
게임서버프로그래밍 #4 - 멀티스레드 프로그래밍Seungmo Koo
 
[Unite2015 박민근] 유니티 최적화 테크닉 총정리
[Unite2015 박민근] 유니티 최적화 테크닉 총정리[Unite2015 박민근] 유니티 최적화 테크닉 총정리
[Unite2015 박민근] 유니티 최적화 테크닉 총정리MinGeun Park
 
맛만 보자 액터 모델이란
맛만 보자 액터 모델이란 맛만 보자 액터 모델이란
맛만 보자 액터 모델이란 jbugkorea
 
Modern C++ 프로그래머를 위한 CPP11/14 핵심
Modern C++ 프로그래머를 위한 CPP11/14 핵심Modern C++ 프로그래머를 위한 CPP11/14 핵심
Modern C++ 프로그래머를 위한 CPP11/14 핵심흥배 최
 

What's hot (20)

시즌 2: 멀티쓰레드 프로그래밍이 왜이리 힘드나요?
시즌 2: 멀티쓰레드 프로그래밍이 왜이리 힘드나요?시즌 2: 멀티쓰레드 프로그래밍이 왜이리 힘드나요?
시즌 2: 멀티쓰레드 프로그래밍이 왜이리 힘드나요?
 
중앙 서버 없는 게임 로직
중앙 서버 없는 게임 로직중앙 서버 없는 게임 로직
중앙 서버 없는 게임 로직
 
Multiplayer Game Sync Techniques through CAP theorem
Multiplayer Game Sync Techniques through CAP theoremMultiplayer Game Sync Techniques through CAP theorem
Multiplayer Game Sync Techniques through CAP theorem
 
LockFree Algorithm
LockFree AlgorithmLockFree Algorithm
LockFree Algorithm
 
MMOG Server-Side 충돌 및 이동처리 설계와 구현
MMOG Server-Side 충돌 및 이동처리 설계와 구현MMOG Server-Side 충돌 및 이동처리 설계와 구현
MMOG Server-Side 충돌 및 이동처리 설계와 구현
 
Ndc2014 시즌 2 : 멀티쓰레드 프로그래밍이 왜 이리 힘드나요? (Lock-free에서 Transactional Memory까지)
Ndc2014 시즌 2 : 멀티쓰레드 프로그래밍이  왜 이리 힘드나요?  (Lock-free에서 Transactional Memory까지)Ndc2014 시즌 2 : 멀티쓰레드 프로그래밍이  왜 이리 힘드나요?  (Lock-free에서 Transactional Memory까지)
Ndc2014 시즌 2 : 멀티쓰레드 프로그래밍이 왜 이리 힘드나요? (Lock-free에서 Transactional Memory까지)
 
Lock free queue
Lock free queueLock free queue
Lock free queue
 
Tcp ip & io model
Tcp ip & io modelTcp ip & io model
Tcp ip & io model
 
Akka.NET 으로 만드는 온라인 게임 서버 (NDC2016)
Akka.NET 으로 만드는 온라인 게임 서버 (NDC2016)Akka.NET 으로 만드는 온라인 게임 서버 (NDC2016)
Akka.NET 으로 만드는 온라인 게임 서버 (NDC2016)
 
게임프로젝트에 적용하는 GPGPU
게임프로젝트에 적용하는 GPGPU게임프로젝트에 적용하는 GPGPU
게임프로젝트에 적용하는 GPGPU
 
[야생의 땅: 듀랑고] 서버 아키텍처 Vol. 2 (자막)
[야생의 땅: 듀랑고] 서버 아키텍처 Vol. 2 (자막)[야생의 땅: 듀랑고] 서버 아키텍처 Vol. 2 (자막)
[야생의 땅: 듀랑고] 서버 아키텍처 Vol. 2 (자막)
 
게임서버프로그래밍 #1 - IOCP
게임서버프로그래밍 #1 - IOCP게임서버프로그래밍 #1 - IOCP
게임서버프로그래밍 #1 - IOCP
 
게임서버프로그래밍 #2 - IOCP Adv
게임서버프로그래밍 #2 - IOCP Adv게임서버프로그래밍 #2 - IOCP Adv
게임서버프로그래밍 #2 - IOCP Adv
 
홍성우, 게임 서버의 목차 - 시작부터 출시까지, NDC2019
홍성우, 게임 서버의 목차 - 시작부터 출시까지, NDC2019홍성우, 게임 서버의 목차 - 시작부터 출시까지, NDC2019
홍성우, 게임 서버의 목차 - 시작부터 출시까지, NDC2019
 
임태현, MMO 서버 개발 포스트 모템, NDC2012
임태현, MMO 서버 개발 포스트 모템, NDC2012임태현, MMO 서버 개발 포스트 모템, NDC2012
임태현, MMO 서버 개발 포스트 모템, NDC2012
 
게임서버프로그래밍 #4 - 멀티스레드 프로그래밍
게임서버프로그래밍 #4 - 멀티스레드 프로그래밍게임서버프로그래밍 #4 - 멀티스레드 프로그래밍
게임서버프로그래밍 #4 - 멀티스레드 프로그래밍
 
[Unite2015 박민근] 유니티 최적화 테크닉 총정리
[Unite2015 박민근] 유니티 최적화 테크닉 총정리[Unite2015 박민근] 유니티 최적화 테크닉 총정리
[Unite2015 박민근] 유니티 최적화 테크닉 총정리
 
TBB 소개
TBB 소개TBB 소개
TBB 소개
 
맛만 보자 액터 모델이란
맛만 보자 액터 모델이란 맛만 보자 액터 모델이란
맛만 보자 액터 모델이란
 
Modern C++ 프로그래머를 위한 CPP11/14 핵심
Modern C++ 프로그래머를 위한 CPP11/14 핵심Modern C++ 프로그래머를 위한 CPP11/14 핵심
Modern C++ 프로그래머를 위한 CPP11/14 핵심
 

Viewers also liked

[Windows via c/c++] 4장 프로세스
[Windows via c/c++] 4장 프로세스[Windows via c/c++] 4장 프로세스
[Windows via c/c++] 4장 프로세스종빈 오
 
트위터 봇 개발 후기
트위터 봇 개발 후기트위터 봇 개발 후기
트위터 봇 개발 후기종빈 오
 
Visual C++10을 활용한 병렬 프로그래밍
Visual C++10을 활용한 병렬 프로그래밍Visual C++10을 활용한 병렬 프로그래밍
Visual C++10을 활용한 병렬 프로그래밍흥배 최
 
Windws via c/c++ chapter 6
Windws via c/c++ chapter 6Windws via c/c++ chapter 6
Windws via c/c++ chapter 6SukYun Yoon
 
그녀가언어를익히는방법
그녀가언어를익히는방법그녀가언어를익히는방법
그녀가언어를익히는방법Yoon Hee Hwang
 
xUnitTestPattern/chapter17
xUnitTestPattern/chapter17xUnitTestPattern/chapter17
xUnitTestPattern/chapter17Yoon Hee Hwang
 
[아꿈사/110903] 도메인주도설계 4장
[아꿈사/110903] 도메인주도설계 4장[아꿈사/110903] 도메인주도설계 4장
[아꿈사/110903] 도메인주도설계 4장sung ki choi
 
Timing wheels
Timing wheelsTiming wheels
Timing wheelssupperniu
 
[111015/아꿈사] HTML5를 여행하는 비(非) 웹 개발자를 위한 안내서 - 1부 웹소켓.
[111015/아꿈사] HTML5를 여행하는 비(非) 웹 개발자를 위한 안내서 - 1부 웹소켓.[111015/아꿈사] HTML5를 여행하는 비(非) 웹 개발자를 위한 안내서 - 1부 웹소켓.
[111015/아꿈사] HTML5를 여행하는 비(非) 웹 개발자를 위한 안내서 - 1부 웹소켓.sung ki choi
 
[120316] node.js 프로그래밍 5장
[120316] node.js 프로그래밍 5장[120316] node.js 프로그래밍 5장
[120316] node.js 프로그래밍 5장sung ki choi
 
[아꿈사] 게임 기초 수학 물리 1,2장
[아꿈사] 게임 기초 수학 물리 1,2장[아꿈사] 게임 기초 수학 물리 1,2장
[아꿈사] 게임 기초 수학 물리 1,2장sung ki choi
 
[TAOCP] 2.2.3 연결된 할당 - 위상정렬
[TAOCP] 2.2.3 연결된 할당 - 위상정렬[TAOCP] 2.2.3 연결된 할당 - 위상정렬
[TAOCP] 2.2.3 연결된 할당 - 위상정렬종빈 오
 
프로그래머가 몰랐던 멀티코어 CPU 이야기 13, 14장
프로그래머가 몰랐던 멀티코어 CPU 이야기 13, 14장프로그래머가 몰랐던 멀티코어 CPU 이야기 13, 14장
프로그래머가 몰랐던 멀티코어 CPU 이야기 13, 14장SukYun Yoon
 
ApprenticeshipPatterns/Chapter3
ApprenticeshipPatterns/Chapter3ApprenticeshipPatterns/Chapter3
ApprenticeshipPatterns/Chapter3Yoon Hee Hwang
 
Intrusive data structure 소개
Intrusive data structure 소개Intrusive data structure 소개
Intrusive data structure 소개종빈 오
 
이승재, M2 AI코드 개발 생산성 향상 사례, NDC2013
이승재, M2 AI코드 개발 생산성 향상 사례, NDC2013이승재, M2 AI코드 개발 생산성 향상 사례, NDC2013
이승재, M2 AI코드 개발 생산성 향상 사례, NDC2013devCAT Studio, NEXON
 
온라인 게임 처음부터 끝까지 동적언어로 만들기
온라인 게임 처음부터 끝까지 동적언어로 만들기온라인 게임 처음부터 끝까지 동적언어로 만들기
온라인 게임 처음부터 끝까지 동적언어로 만들기Seungjae Lee
 
서버 성능에 대한 정의와 이해
서버 성능에 대한 정의와 이해서버 성능에 대한 정의와 이해
서버 성능에 대한 정의와 이해중선 곽
 

Viewers also liked (19)

[Windows via c/c++] 4장 프로세스
[Windows via c/c++] 4장 프로세스[Windows via c/c++] 4장 프로세스
[Windows via c/c++] 4장 프로세스
 
트위터 봇 개발 후기
트위터 봇 개발 후기트위터 봇 개발 후기
트위터 봇 개발 후기
 
Visual C++10을 활용한 병렬 프로그래밍
Visual C++10을 활용한 병렬 프로그래밍Visual C++10을 활용한 병렬 프로그래밍
Visual C++10을 활용한 병렬 프로그래밍
 
Windws via c/c++ chapter 6
Windws via c/c++ chapter 6Windws via c/c++ chapter 6
Windws via c/c++ chapter 6
 
그녀가언어를익히는방법
그녀가언어를익히는방법그녀가언어를익히는방법
그녀가언어를익히는방법
 
Nodejs_chapter3
Nodejs_chapter3Nodejs_chapter3
Nodejs_chapter3
 
xUnitTestPattern/chapter17
xUnitTestPattern/chapter17xUnitTestPattern/chapter17
xUnitTestPattern/chapter17
 
[아꿈사/110903] 도메인주도설계 4장
[아꿈사/110903] 도메인주도설계 4장[아꿈사/110903] 도메인주도설계 4장
[아꿈사/110903] 도메인주도설계 4장
 
Timing wheels
Timing wheelsTiming wheels
Timing wheels
 
[111015/아꿈사] HTML5를 여행하는 비(非) 웹 개발자를 위한 안내서 - 1부 웹소켓.
[111015/아꿈사] HTML5를 여행하는 비(非) 웹 개발자를 위한 안내서 - 1부 웹소켓.[111015/아꿈사] HTML5를 여행하는 비(非) 웹 개발자를 위한 안내서 - 1부 웹소켓.
[111015/아꿈사] HTML5를 여행하는 비(非) 웹 개발자를 위한 안내서 - 1부 웹소켓.
 
[120316] node.js 프로그래밍 5장
[120316] node.js 프로그래밍 5장[120316] node.js 프로그래밍 5장
[120316] node.js 프로그래밍 5장
 
[아꿈사] 게임 기초 수학 물리 1,2장
[아꿈사] 게임 기초 수학 물리 1,2장[아꿈사] 게임 기초 수학 물리 1,2장
[아꿈사] 게임 기초 수학 물리 1,2장
 
[TAOCP] 2.2.3 연결된 할당 - 위상정렬
[TAOCP] 2.2.3 연결된 할당 - 위상정렬[TAOCP] 2.2.3 연결된 할당 - 위상정렬
[TAOCP] 2.2.3 연결된 할당 - 위상정렬
 
프로그래머가 몰랐던 멀티코어 CPU 이야기 13, 14장
프로그래머가 몰랐던 멀티코어 CPU 이야기 13, 14장프로그래머가 몰랐던 멀티코어 CPU 이야기 13, 14장
프로그래머가 몰랐던 멀티코어 CPU 이야기 13, 14장
 
ApprenticeshipPatterns/Chapter3
ApprenticeshipPatterns/Chapter3ApprenticeshipPatterns/Chapter3
ApprenticeshipPatterns/Chapter3
 
Intrusive data structure 소개
Intrusive data structure 소개Intrusive data structure 소개
Intrusive data structure 소개
 
이승재, M2 AI코드 개발 생산성 향상 사례, NDC2013
이승재, M2 AI코드 개발 생산성 향상 사례, NDC2013이승재, M2 AI코드 개발 생산성 향상 사례, NDC2013
이승재, M2 AI코드 개발 생산성 향상 사례, NDC2013
 
온라인 게임 처음부터 끝까지 동적언어로 만들기
온라인 게임 처음부터 끝까지 동적언어로 만들기온라인 게임 처음부터 끝까지 동적언어로 만들기
온라인 게임 처음부터 끝까지 동적언어로 만들기
 
서버 성능에 대한 정의와 이해
서버 성능에 대한 정의와 이해서버 성능에 대한 정의와 이해
서버 성능에 대한 정의와 이해
 

Similar to 제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화

[2B7]시즌2 멀티쓰레드프로그래밍이 왜 이리 힘드나요
[2B7]시즌2 멀티쓰레드프로그래밍이 왜 이리 힘드나요[2B7]시즌2 멀티쓰레드프로그래밍이 왜 이리 힘드나요
[2B7]시즌2 멀티쓰레드프로그래밍이 왜 이리 힘드나요NAVER D2
 
android_thread
android_threadandroid_thread
android_threadhandfoot
 
Javascript 조금 더 잘 알기
Javascript 조금 더 잘 알기Javascript 조금 더 잘 알기
Javascript 조금 더 잘 알기jongho jeong
 
파이썬 병렬프로그래밍
파이썬 병렬프로그래밍파이썬 병렬프로그래밍
파이썬 병렬프로그래밍Yong Joon Moon
 
Multi-thread : producer - consumer
Multi-thread : producer - consumerMulti-thread : producer - consumer
Multi-thread : producer - consumerChang Yoon Oh
 
[2D4]Python에서의 동시성_병렬성
[2D4]Python에서의 동시성_병렬성[2D4]Python에서의 동시성_병렬성
[2D4]Python에서의 동시성_병렬성NAVER D2
 
C# / .NET Framework로 미래 밥그릇을 챙겨보자 (Basic)
C# / .NET Framework로 미래 밥그릇을 챙겨보자 (Basic)C# / .NET Framework로 미래 밥그릇을 챙겨보자 (Basic)
C# / .NET Framework로 미래 밥그릇을 챙겨보자 (Basic)Dong Chan Shin
 
Introduction to Fork Join Framework_SYS4U I&C
Introduction to Fork Join Framework_SYS4U I&CIntroduction to Fork Join Framework_SYS4U I&C
Introduction to Fork Join Framework_SYS4U I&Csys4u
 
Effective c++ chapter1 2_dcshin
Effective c++ chapter1 2_dcshinEffective c++ chapter1 2_dcshin
Effective c++ chapter1 2_dcshinDong Chan Shin
 
윈도우 커널 익스플로잇
윈도우 커널 익스플로잇윈도우 커널 익스플로잇
윈도우 커널 익스플로잇Seungyong Lee
 
Concurrent programming
Concurrent programmingConcurrent programming
Concurrent programmingByeongsu Kang
 
안드로이드 빌드: 설탕없는 세계
안드로이드 빌드: 설탕없는 세계안드로이드 빌드: 설탕없는 세계
안드로이드 빌드: 설탕없는 세계Leonardo YongUk Kim
 
Windows via C/C++ 06 스레드의 기본
Windows via C/C++ 06 스레드의 기본Windows via C/C++ 06 스레드의 기본
Windows via C/C++ 06 스레드의 기본ssuser0c2478
 
CUDA 프로그래밍 기초 MODUCON2018
CUDA 프로그래밍 기초 MODUCON2018CUDA 프로그래밍 기초 MODUCON2018
CUDA 프로그래밍 기초 MODUCON2018Shengzhe Li
 
동기화, 스케줄링
동기화, 스케줄링동기화, 스케줄링
동기화, 스케줄링xxbdxx
 
R2서버정진욱
R2서버정진욱R2서버정진욱
R2서버정진욱jungjinwouk
 

Similar to 제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화 (20)

[2B7]시즌2 멀티쓰레드프로그래밍이 왜 이리 힘드나요
[2B7]시즌2 멀티쓰레드프로그래밍이 왜 이리 힘드나요[2B7]시즌2 멀티쓰레드프로그래밍이 왜 이리 힘드나요
[2B7]시즌2 멀티쓰레드프로그래밍이 왜 이리 힘드나요
 
android_thread
android_threadandroid_thread
android_thread
 
Javascript 조금 더 잘 알기
Javascript 조금 더 잘 알기Javascript 조금 더 잘 알기
Javascript 조금 더 잘 알기
 
Java(2/4)
Java(2/4)Java(2/4)
Java(2/4)
 
파이썬 병렬프로그래밍
파이썬 병렬프로그래밍파이썬 병렬프로그래밍
파이썬 병렬프로그래밍
 
Multi-thread : producer - consumer
Multi-thread : producer - consumerMulti-thread : producer - consumer
Multi-thread : producer - consumer
 
[2D4]Python에서의 동시성_병렬성
[2D4]Python에서의 동시성_병렬성[2D4]Python에서의 동시성_병렬성
[2D4]Python에서의 동시성_병렬성
 
MutiCore 19-20
MutiCore 19-20MutiCore 19-20
MutiCore 19-20
 
C# / .NET Framework로 미래 밥그릇을 챙겨보자 (Basic)
C# / .NET Framework로 미래 밥그릇을 챙겨보자 (Basic)C# / .NET Framework로 미래 밥그릇을 챙겨보자 (Basic)
C# / .NET Framework로 미래 밥그릇을 챙겨보자 (Basic)
 
Introduction to Fork Join Framework_SYS4U I&C
Introduction to Fork Join Framework_SYS4U I&CIntroduction to Fork Join Framework_SYS4U I&C
Introduction to Fork Join Framework_SYS4U I&C
 
Node.js 기본
Node.js 기본Node.js 기본
Node.js 기본
 
Effective c++ chapter1 2_dcshin
Effective c++ chapter1 2_dcshinEffective c++ chapter1 2_dcshin
Effective c++ chapter1 2_dcshin
 
윈도우 커널 익스플로잇
윈도우 커널 익스플로잇윈도우 커널 익스플로잇
윈도우 커널 익스플로잇
 
Concurrent programming
Concurrent programmingConcurrent programming
Concurrent programming
 
Gcd ppt
Gcd pptGcd ppt
Gcd ppt
 
안드로이드 빌드: 설탕없는 세계
안드로이드 빌드: 설탕없는 세계안드로이드 빌드: 설탕없는 세계
안드로이드 빌드: 설탕없는 세계
 
Windows via C/C++ 06 스레드의 기본
Windows via C/C++ 06 스레드의 기본Windows via C/C++ 06 스레드의 기본
Windows via C/C++ 06 스레드의 기본
 
CUDA 프로그래밍 기초 MODUCON2018
CUDA 프로그래밍 기초 MODUCON2018CUDA 프로그래밍 기초 MODUCON2018
CUDA 프로그래밍 기초 MODUCON2018
 
동기화, 스케줄링
동기화, 스케줄링동기화, 스케줄링
동기화, 스케줄링
 
R2서버정진욱
R2서버정진욱R2서버정진욱
R2서버정진욱
 

More from sung ki choi

[111217 아꿈사연말모임] 웹소켓과온라인게임
[111217 아꿈사연말모임] 웹소켓과온라인게임[111217 아꿈사연말모임] 웹소켓과온라인게임
[111217 아꿈사연말모임] 웹소켓과온라인게임sung ki choi
 
[아꿈사/111105] html5 9장 클라이언트측 데이터로 작업하기
[아꿈사/111105] html5 9장 클라이언트측 데이터로 작업하기[아꿈사/111105] html5 9장 클라이언트측 데이터로 작업하기
[아꿈사/111105] html5 9장 클라이언트측 데이터로 작업하기sung ki choi
 
[110730/아꿈사발표자료] mongo db 완벽 가이드 : 7장 '고급기능'
[110730/아꿈사발표자료] mongo db 완벽 가이드 : 7장 '고급기능'[110730/아꿈사발표자료] mongo db 완벽 가이드 : 7장 '고급기능'
[110730/아꿈사발표자료] mongo db 완벽 가이드 : 7장 '고급기능'sung ki choi
 
[아꿈사/110528] 멀티코어cpu이야기 5,6장
[아꿈사/110528] 멀티코어cpu이야기 5,6장[아꿈사/110528] 멀티코어cpu이야기 5,6장
[아꿈사/110528] 멀티코어cpu이야기 5,6장sung ki choi
 
[아꿈사/110514] 멀티코어cpu이야기 시작발표
[아꿈사/110514] 멀티코어cpu이야기 시작발표[아꿈사/110514] 멀티코어cpu이야기 시작발표
[아꿈사/110514] 멀티코어cpu이야기 시작발표sung ki choi
 
[110331] visual studio 속성 관리자
[110331] visual studio 속성 관리자[110331] visual studio 속성 관리자
[110331] visual studio 속성 관리자sung ki choi
 
100828 [visual studio camp #1] C++0x와 Windows7
100828 [visual studio camp #1] C++0x와 Windows7100828 [visual studio camp #1] C++0x와 Windows7
100828 [visual studio camp #1] C++0x와 Windows7sung ki choi
 
110212 [아꿈사발표자료] taocp#1 1.2.8. 피보나치수열
110212 [아꿈사발표자료] taocp#1 1.2.8. 피보나치수열110212 [아꿈사발표자료] taocp#1 1.2.8. 피보나치수열
110212 [아꿈사발표자료] taocp#1 1.2.8. 피보나치수열sung ki choi
 
101102 endofdb select.1_rdbms
101102 endofdb select.1_rdbms101102 endofdb select.1_rdbms
101102 endofdb select.1_rdbmssung ki choi
 
100526 windows7 mfc_최성기_배포용
100526 windows7 mfc_최성기_배포용100526 windows7 mfc_최성기_배포용
100526 windows7 mfc_최성기_배포용sung ki choi
 
100511 boost&tips 최성기
100511 boost&tips 최성기100511 boost&tips 최성기
100511 boost&tips 최성기sung ki choi
 
Touch Ux With Win32
Touch Ux With Win32Touch Ux With Win32
Touch Ux With Win32sung ki choi
 

More from sung ki choi (12)

[111217 아꿈사연말모임] 웹소켓과온라인게임
[111217 아꿈사연말모임] 웹소켓과온라인게임[111217 아꿈사연말모임] 웹소켓과온라인게임
[111217 아꿈사연말모임] 웹소켓과온라인게임
 
[아꿈사/111105] html5 9장 클라이언트측 데이터로 작업하기
[아꿈사/111105] html5 9장 클라이언트측 데이터로 작업하기[아꿈사/111105] html5 9장 클라이언트측 데이터로 작업하기
[아꿈사/111105] html5 9장 클라이언트측 데이터로 작업하기
 
[110730/아꿈사발표자료] mongo db 완벽 가이드 : 7장 '고급기능'
[110730/아꿈사발표자료] mongo db 완벽 가이드 : 7장 '고급기능'[110730/아꿈사발표자료] mongo db 완벽 가이드 : 7장 '고급기능'
[110730/아꿈사발표자료] mongo db 완벽 가이드 : 7장 '고급기능'
 
[아꿈사/110528] 멀티코어cpu이야기 5,6장
[아꿈사/110528] 멀티코어cpu이야기 5,6장[아꿈사/110528] 멀티코어cpu이야기 5,6장
[아꿈사/110528] 멀티코어cpu이야기 5,6장
 
[아꿈사/110514] 멀티코어cpu이야기 시작발표
[아꿈사/110514] 멀티코어cpu이야기 시작발표[아꿈사/110514] 멀티코어cpu이야기 시작발표
[아꿈사/110514] 멀티코어cpu이야기 시작발표
 
[110331] visual studio 속성 관리자
[110331] visual studio 속성 관리자[110331] visual studio 속성 관리자
[110331] visual studio 속성 관리자
 
100828 [visual studio camp #1] C++0x와 Windows7
100828 [visual studio camp #1] C++0x와 Windows7100828 [visual studio camp #1] C++0x와 Windows7
100828 [visual studio camp #1] C++0x와 Windows7
 
110212 [아꿈사발표자료] taocp#1 1.2.8. 피보나치수열
110212 [아꿈사발표자료] taocp#1 1.2.8. 피보나치수열110212 [아꿈사발표자료] taocp#1 1.2.8. 피보나치수열
110212 [아꿈사발표자료] taocp#1 1.2.8. 피보나치수열
 
101102 endofdb select.1_rdbms
101102 endofdb select.1_rdbms101102 endofdb select.1_rdbms
101102 endofdb select.1_rdbms
 
100526 windows7 mfc_최성기_배포용
100526 windows7 mfc_최성기_배포용100526 windows7 mfc_최성기_배포용
100526 windows7 mfc_최성기_배포용
 
100511 boost&tips 최성기
100511 boost&tips 최성기100511 boost&tips 최성기
100511 boost&tips 최성기
 
Touch Ux With Win32
Touch Ux With Win32Touch Ux With Win32
Touch Ux With Win32
 

Recently uploaded

Continual Active Learning for Efficient Adaptation of Machine LearningModels ...
Continual Active Learning for Efficient Adaptation of Machine LearningModels ...Continual Active Learning for Efficient Adaptation of Machine LearningModels ...
Continual Active Learning for Efficient Adaptation of Machine LearningModels ...Kim Daeun
 
캐드앤그래픽스 2024년 5월호 목차
캐드앤그래픽스 2024년 5월호 목차캐드앤그래픽스 2024년 5월호 목차
캐드앤그래픽스 2024년 5월호 목차캐드앤그래픽스
 
MOODv2 : Masked Image Modeling for Out-of-Distribution Detection
MOODv2 : Masked Image Modeling for Out-of-Distribution DetectionMOODv2 : Masked Image Modeling for Out-of-Distribution Detection
MOODv2 : Masked Image Modeling for Out-of-Distribution DetectionKim Daeun
 
Merge (Kitworks Team Study 이성수 발표자료 240426)
Merge (Kitworks Team Study 이성수 발표자료 240426)Merge (Kitworks Team Study 이성수 발표자료 240426)
Merge (Kitworks Team Study 이성수 발표자료 240426)Wonjun Hwang
 
A future that integrates LLMs and LAMs (Symposium)
A future that integrates LLMs and LAMs (Symposium)A future that integrates LLMs and LAMs (Symposium)
A future that integrates LLMs and LAMs (Symposium)Tae Young Lee
 
Console API (Kitworks Team Study 백혜인 발표자료)
Console API (Kitworks Team Study 백혜인 발표자료)Console API (Kitworks Team Study 백혜인 발표자료)
Console API (Kitworks Team Study 백혜인 발표자료)Wonjun Hwang
 

Recently uploaded (6)

Continual Active Learning for Efficient Adaptation of Machine LearningModels ...
Continual Active Learning for Efficient Adaptation of Machine LearningModels ...Continual Active Learning for Efficient Adaptation of Machine LearningModels ...
Continual Active Learning for Efficient Adaptation of Machine LearningModels ...
 
캐드앤그래픽스 2024년 5월호 목차
캐드앤그래픽스 2024년 5월호 목차캐드앤그래픽스 2024년 5월호 목차
캐드앤그래픽스 2024년 5월호 목차
 
MOODv2 : Masked Image Modeling for Out-of-Distribution Detection
MOODv2 : Masked Image Modeling for Out-of-Distribution DetectionMOODv2 : Masked Image Modeling for Out-of-Distribution Detection
MOODv2 : Masked Image Modeling for Out-of-Distribution Detection
 
Merge (Kitworks Team Study 이성수 발표자료 240426)
Merge (Kitworks Team Study 이성수 발표자료 240426)Merge (Kitworks Team Study 이성수 발표자료 240426)
Merge (Kitworks Team Study 이성수 발표자료 240426)
 
A future that integrates LLMs and LAMs (Symposium)
A future that integrates LLMs and LAMs (Symposium)A future that integrates LLMs and LAMs (Symposium)
A future that integrates LLMs and LAMs (Symposium)
 
Console API (Kitworks Team Study 백혜인 발표자료)
Console API (Kitworks Team Study 백혜인 발표자료)Console API (Kitworks Team Study 백혜인 발표자료)
Console API (Kitworks Team Study 백혜인 발표자료)
 

제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화

  • 1. 유저 모드에서의 스레드 동기화 Thread Synchronization in User Mode 아꿈사 http://cafe.naver.com/architect1 최성기 florist.sk@gmail.com
  • 2. 1. 원자적 접근 : Interlocked 함수들 2. 캐시 라인 3. 고급 스레드 동기화 기법 4. 크리티컬 섹션 5. 슬림 리더-라이터 락 6. 조건변수
  • 3. 1. 원자적 접근 : Interlocked 함수들 2. 캐시 라인 3. 고급 스레드 동기화 기법 4. 크리티컬 섹션 5. 슬림 리더-라이터 락 6. 조건변수
  • 4. 어떤 스레드가 특정 리소스를 접근할 때 다른 스레드는 동일 시간에 동일 리소스에 접근할 수 없는 것을 말한다. a thread's ability to access a resource with the guarantee that no other thread will access that same resource at the same time.
  • 5. int g_x = 10; 스레드 1 스레드 2 void func() { assert( g_x != 0 ); ... g_x = 0; ... g_x = 10; } 병렬실행을 고려하지 않은 코드가 동시에 실행되면서 공유자원의 값이 예측 불가능한 것도 문제긴 하지만
  • 6. int g_x = 0; 스레드 1 스레드 2 void func() { g_x++; } = 원자적으로 보이는 명령 코드상으로는 괜찮아 보이는 경우에도 병렬 실행시 이상해 지는 경우가 있다. = 원자적이지 않다는 소리
  • 7. C++ 코드 x86 어셈블리 코드 MOV EAX, [g_x] g_x++; INC EAX MOV [g_x], EAX C++에서 한 줄의 명령어로 표현 되더라도 컴파일된 어셈블리 코드는 여러 단계로 나뉘어져 동시에 실행됨을 보장할 수 없는 경우가 있다.
  • 8. int g_x = 0; 스레드 1 스레드 2 void func() { // g_x++; MOV EAX, [g_x] INC EAX MOV [g_x], EAX } 이렇게 풀어서 써보면 처음과 비슷해짐.
  • 9. int i = 0; int j = 20; vs2010, x86, debug i = i + 1; mov eax,dword ptr [i] add eax,1 i++; mov dword ptr [i],eax ++i; mov eax,dword ptr [j] mov dword ptr [i],eax i = j; mov dword ptr [i],15h i = 21; 다음 중 원자적인 연산은?
  • 10. int i = 0; int j = 20; vs2010, x86, release (/O2) i = i + 1; inc dword ptr [ebp-4] ?? i++; ++i; mov eax,dword ptr [ebp-8] push esi i = j; mov dword ptr [ebp-4],15h i = 21; x86 명령어셋은 메모리값을 1증가시키는 단일명령어 inc도 지원 하나의 기계어라도 CISC 명령어가 내부 파이프라인으로 들어가면 결국 레지스터로 load – add – store하는 마이크로 명령어로 분해될 수 있음을 유의해야 한다. 337p.
  • 11. int g_x = 0; void func() { lock(); g_x++; unlock(); } 아니 그럼 멀티 스레드 에서는 고작 정수형 변수 하나 건드릴 때에도 매번 락을 걸어야 하나요?
  • 12. 이런 절차로 어린 코더가 니르고저 할빼이셔도 비로서 제 뜻을 시러 펴디 못할 노미 하니라. InterlockedExchangeAdd( 변수주소, 값 ); InterlockedExchangeAdd64( 변수주소, 값 ); InterlockedExchange( 변수주소, 값 ); InterlockedExchange64( 변수주소, 값 ); InterlockedExchangePointer( 변수주소, 값 ); InterlockedIncrement( 변수주소 ); InterlockedDecrement( 변수주소 ); …
  • 13. int g_x = 0; int g_x = 0; void func() void func() { { lock(); g_x++; InterlockedExchangeAdd( &g_x, 1 ); unlock(); } } 정수형 변수의 값을 원자적으로 다뤄야 할 때 인터락 함수를 이용하면 된다.  빠르게 수행됨 (50사이클 미만)  유저모드 – 커널모드의 전환을 일으키지 않음.
  • 14. // 공유 리소스의 사용 여부를 나타내는 전역변수 BOOL g_fResourceInUse = FALSE; ... void Func1() { // 리소스의 접근을 기다림 while (InterlockedExchange(&g_fResourceInUse, TRUE) == TRUE) Sleep(0); // 리소스에 접근함 ... // 리소스에 더 이상 접근할 필요가 없음 InterlockedExchange(&g_fResourceInUse, FALSE); } InterlockedExchange는 특별히 스핀락spinlock을 구현해야 하는 경우에 유용하게 사용될 수 있다.
  • 15. 값의 비교와 변경을 원자적으로 해주는 연산. 멀티스레드 프로그래밍에 필수적인 뮤텍스, 세마포등의 동기화 객체synchronization object를 만드는 데 쓰인다. InterlockedCompareExchange( 변수주소, 변경값, 비교값 ); InterlockedCompareExchange64( … ); InterlockedCompareExchangePointer( … );
  • 16. void mutex_lock( int* lock_var ) { while( InterlockedCompareExchange( lock_var, 0, 1 ) ); } void mutex_unlock( int* lock_var ) { *lock_var = 0; } CAS 연산만을 가지고 구현한 lock / unlock 함수. 338p.
  • 17. 스레드 1 스레드 2 x == A x = B x = A x == A CAS 연산이 다른 스레드의 접근을 감지하지 못하는 현상. Interlocked Singly Linked List 사용시 주의점. - http://devnote.tistory.com/207
  • 18. 1. 원자적 접근 : Interlocked 함수들 2. 캐시 라인 3. 고급 스레드 동기화 기법 4. 크리티컬 섹션 5. 슬림 리더-라이터 락 6. 조건변수
  • 19. 정말 최적화된 프로그램을 작성하고 싶다면 캐시 미스(cache miss)가 적게 일어나도록 신경써야 한다. http://goo.gl/7j5yP 인접한 메모리 데이터는 같은 캐시라인으로 구성되어 코어마다 분리된 캐시에 적재되기 때문.
  • 20. 1. CPU1이 메모리 1000번지 값을 읽는다. 234p. • 값을 읽어 캐시에 보관 2. CPU2도 메모리 1000번지 값을 읽는다. • 값을 읽어 캐시에 보관 3. CPU1이 메모리 1000번지 값을 변경한다. • 캐시의 값 변경. 아직 RAM에 쓰기 전. 4. CPU2가 다시 1000번지 값을 읽는다. • 자신의 캐시에 값이 있지만 최신 내용이 아님. cache coherence miss 발생.
  • 21. 1. 읽기 전용의 데이터와 읽고쓰는 데이터를 분리 2. 동일 시간에 접근하는 데이터를 묶어서 구성 3. CPU의 캐시라인 크기를 알아내서, 데이터 정렬을 캐시라인 크기별로 구성. 캐시라인 크기 알아내기 : GetLogicalProcessorInformation() - http://goo.gl/MVZPH 구조체 정렬 임의로 조절하기 : __declspec(align(#)) - http://pmguda.com/378 - http://goo.gl/w8SyL
  • 22. 1. 원자적 접근 : Interlocked 함수들 2. 캐시 라인 3. 고급 스레드 동기화 기법 4. 크리티컬 섹션 5. 슬림 리더-라이터 락 스핀락 vs 대기모드 전역변수 스핀락(?) 6. 조건변수 volatile 키워드.
  • 23. 1. 원자적 접근 : Interlocked 함수들 2. 캐시 라인 3. 고급 스레드 동기화 기법 4. 크리티컬 섹션 5. 슬림 리더-라이터 락 6. 조건변수
  • 24. 공유 리소스에 대해 배타적으로 접근해야 하는 작은 코드의 집합을 의미한다. 공유 리소스를 다루는 여러 줄의 코드를 원자적으로 수행하기 위한 방법이다.
  • 25. 인터락 함수로 동기화를 해결할 수 없다면 크리티컬 섹션을 사용하라. 장점 • 사용이 쉽고 내부적으로 인터락 함수를 사용해 빠르다. 단점 • 서로 다른 프로세스의 스레드 간에는 사용할 수 없다.
  • 26. int g_x = 0; void func() { EnterCriticalSection( &g_cs ); for( int i = 0; i < 1000; i++ ) { Critical g_x += i; Section } LeaveCriticalSection( &g_cs ); } 크리티컬 섹션으로 둘러쌓인 코드는 동시에 하나의 스레드밖에 진입할 수 없다.
  • 27. 1. 이미 Critical Section에 진입한 스레드가 다시 Enter 해도 괜찮다. 단, Enter 횟수만큼 Leave 해주어야 한다. 2. 다른 스레드가 진입해 있다면 뒤에 호출한 스레드는 이벤트 커널 오브젝트를 이용해 대기 상태로 전환.
  • 28. 스레드를 절대 대기 상태로 진입시키지 않는다. 호출한 스레드가 진입해 성공했다면 TRUE 반환, 다른 스레드가 이미 진입해서 실패했다면 FALSE 반환.
  • 29. 스레드가 스핀락spinlock을 돌면서 대기하면  CPU 시간을 소모하면서 대기하는 방식.  대기 시간이 길어지면 CPU자원의 낭비가 된다. 스레드가 운영체제의 대기상태wait state로 전환되면  CPU 자원을 낭비하지 않는다.  대기 시간이 길어질 수록 효율적인 대기방식.
  • 30. 스레드가 스핀락spinlock을 돌면서 대기하면  CPU 시간을 소모하면서 대기하는 방식.  대기 시간이 길어지면 CPU자원의 낭비가 된다.  대기 시간이 짧다면 바로 자원 획득이 가능. 스레드가 운영체제의 대기상태wait state로 전환되면  CPU 자원을 낭비하지 않는다.  대기 시간이 길어질 수록 효율적인 대기방식.  커널모드로 전환되어야 함. 대기 시간이 짧을 때는 오히려 상당한 CPU 낭비.
  • 31. 그래서 이 둘을 합쳐, EnterCriticalSection이 호출되면 1. 일정 횟수 스핀락으로 루프를 돌아 대기. 2. 지정된 횟수 동안 리소스 획득에 실패했다면 커널 모드로 전환해 스레드를 대기 상태로 전환. 하는 방식으로 사용할 수 있게 되어있다.
  • 32. 크리티컬 섹션에 스핀락을 사용하기 위한 초기화 InitializeCriticalSection(…) BOOL InitializeCriticalSectionAndSpinCount( PCRITICAL_SECTION pcs, DWORD dwSpinCount ); 스핀 횟수를 중간에 변경 VOID SetCriticalSectionSpinCount( PCRITICAL_SECTION pcs, DWORD dwSpinCount );
  • 33. 주의 : InitializeCriticalSection 는 가끔 예외를 던진다. 시스템 가용메모리가 모자라 블록 할당이 실패하면 STATUS_NO_MEMORY 예외가 발생. 초기 설계시에 리턴값을 VOID로 해버려서.. 방법이 없다능.. ..AndSpinCount 함수는 동일 상황에 FALSE를 리턴한다. 해결책 : 1. exception handling 처리를 하거나 2. …AndSpinCount 함수를 쓸 것.
  • 34. 주의 : EnterCriticalSection 도 가끔 예외를 던진다. 시스템 메모리가 모자라면 이벤트 객체 생성에 실패하면서 EXCEPTION_INVALID_HANDLE 예외가 발생. 예외가 생뚱맞아서 막상 해당 상황을 디버깅 하려면 헤맬 수 있다. 단, XP 이전의 운영체제에서만 예외가 발생한다. XP부터는 키 이벤트key event라는 객체가 생겨서 이를 사용함. 해결책 : 1. XP 이전 OS를 버리세요. 2. 스핀카운트 최상위비트를 설정해 초기화. 초기화 시점에 미리 이벤트 객체가 생성됨.
  • 35. 책에서는 CRITICAL_SECTION 구조체의 변수 값은 알 필요 없다고 하고 설명도 없는데 데드락을 디버깅하는 데 많은 도움이 됩니다. MSDN 매거진 자료 링크 : http://goo.gl/OGY0M
  • 36. 1. 원자적 접근 : Interlocked 함수들 2. 캐시 라인 3. 고급 스레드 동기화 기법 4. 크리티컬 섹션 5. 슬림 리더-라이터 락 6. 조건변수
  • 37. Read/Write lock은 고전적인 동기화 기법의 하나. http://devnote.tistory.com/177 Write 작업은 한 번에 하나밖에 실행될 수 없지만 Read 작업은 동시에 여러 개가 실행될 수 있게 처리. http://goo.gl/u9TUN 이런 동기화 방식을 Windows Vista / 2008 Server부터 Win32 API 자체적으로 지원한다.
  • 38. 사용 방식은 CriticalSection과 매우 흡사하다. 동작 CriticalSection SRWLock 초기화 InitializeCriticalSection InitializeSRWLock 릴리즈 DeleteCriticalSection 없음 Lock EnterCriticalSection AcquireSRWLockExclusive (Write) ActuireSRWLockShared (Read) Unlock DeleteCriticalSection ReleaseSRWLockExclusive (Write) ReleaseSRWLockShared (Read) TryLock TryEnterCriticalSection TryAcquireSRWLockExclusive (Write) TryAcquireSRWLockShared (Read)
  • 39. 책에는 TryEnter(Shared/Exclusive)SRWLock 함수가 없다고 나오지만 현재는 추가되었음(308p). 이전의 API들보다 늦게 추가되었으며 Windows 7 / Server 2008 R2 이상에서만 지원된다.
  • 40. 스레드/ volatile volatile Interlocked 크리티컬 SRWLock SRWLock 뮤텍스 밀리초 변수 읽기 변수 쓰기 Increment 섹션 Shared Exclusive 1 8 8 35 66 66 67 1060 2 8 76 153 268 134 148 11082 4 9 145 361 768 244 307 23785 벤치마크에 사용된 코드를 보면 크리티컬 섹션은 스핀락을 사용하지 않은 경우. - 크리티컬 섹션과 뮤텍스 모두 커널모드로 전환이 발생하나 뮤텍스는 커널모드 전환비용 이상의 코스트가 발생한다.
  • 41. 1. 원자적 접근 : Interlocked 함수들 2. 캐시 라인 3. 고급 스레드 동기화 기법 4. 크리티컬 섹션 5. 슬림 리더-라이터 락 6. 조건변수
  • 42. http://goo.gl/T8uBM Slim Reader/Writer Lock과 함께 Vista / 2008 Server부터 지원. 조건변수condition variable 역시 병렬처리 이론적으로는 예전부터 정립되어 있는 개념이며 자바나 C#의 Monitor 클래스가 이를 구현하고 있고 POSIX 스레드에도 들어있던 기능. boost::thread에도 구현되어 있다. ACE에도 있는 것 같..지만 제가 ACE를 제대로 본 적이 없네요..
  • 43. 조건변수를 사용하면 스레드가 리소스에 대한 락을 해제하고 SleepConditionVariable*함수에서 지정한 상태가 될 때까지 스레드를 블로킹 해준다. BOOL SleepConditionVariableCS( PCONDITION_VARIABLE pConditionVariable, PCRITICAL_SECTION pCriticalSection, DWORD dwMilliseconds ); BOOL SleepConditionVariableSRW( PCONDITION_VARIABLE pConditionVariable, PSRWLOCK pSRWLock, DWORD dwMilliseconds, ULONG Flags ); // 읽기, 쓰기 구분 플래그
  • 44. CONDITION_VARIABLE cond; InitializeConditionVariable( &cond ); EnterCriticalSection( &cs ); … while( !프로세스 종료상황 ) { if( 지금 작업 가능한 상황 ) { … 씐나게 작업을 한다. } else // 작업 불가능. { SleepConditionVariableCS( &cond, &cs, INFINITE ); } } LeaveCriticalSection( &cs );
  • 45. 조건변수를 이용해 Sleep한 스레드를 깨워야 할 때는 Wake*ConditionVariable 함수로 하나 혹은 모든 스레드를 wake 시킬 수 있다. VOID WakeConditionVariable( PCONDITION_VARIABLE pConditionVariable ); VOID WakeAllConditionVariable( PCONDITION_VARIABLE pConditionVariable );
  • 46. 1. 원자적으로 관리되어야 하는 오브젝트 집합당 하나의 락만을 사용하라. 2. 다수의 논리적 리소스에 동시에 접근하려면 다수의 리소스 락을 원자적으로 설정해야 한다. 스레드1 스레드2 Enter..( &cs1 ); Enter..( &cs2 ); Enter..( &cs2 ); Enter..( &cs1 ); 3. 락을 장시간 점유하지 말 것. 장시간 작업이 필요할 땐 리소스를 복사해서 사용
  • 47. 1. 원자적 접근 : Interlocked 함수들 2. 캐시 라인 3. 고급 스레드 동기화 기법 4. 크리티컬 섹션 5. 슬림 리더-라이터 락 6. 조건변수
  • 48. 유저 모드에서의 스레드 동기화 Thread Synchronization in User Mode 끝♥