Win 32 스 레 드 지식 점 정리 2

10929 단어 다 중 스 레 드
Win 32 에서 sendmessage () 는 동기 화 행위 이 고 PostMessage () 는 비동기 행위 입 니 다.프로 세 스 와 스 레 드 에 대한 조율 작업 은 동기 화 메커니즘 에 의 해 이 루어 진다.
중요 섹 션 임계 구역
그것 의 의 미 는 공 유 된 자원 을 처리 하 는 데 사용 되 는 작은 덩어리 를 말한다. 이곳 의 자원 은 하나의 메모리, 하나의 데이터 구조, 하나의 파일 또는 다른 배타 적 인 것 을 말한다.자원 에 대한 보 호 는 한 번 에 하나의 스 레 드 만 critical section 에 들 어 갈 수 있 도록 하 는 것 입 니 다.메모: Critical Section 은 핵심 대상 이 아 닙 니 다. handle 같은 것 은 프로 세 스 의 메모리 공간 에 존재 합 니 다. Create 와 같은 API 함 수 를 사용 하여 critical section handle 을 얻 을 필요 가 없습니다.
당신 이 해 야 할 일 은 CRITICAL 입 니 다.SECTION 의 변 수 를 초기 화 합 니 다.초기 화 Critical Section 호출
void WINAPI InitializeCriticalSection(
  _Out_ LPCRITICAL_SECTION lpCriticalSection
);

매개 변수 1: 1 개의 포인터, 초기 화 하려 는 critical섹 션 변수
void WINAPI DeleteCriticalSection(
  _Inout_ LPCRITICAL_SECTION lpCriticalSection
);

인자 1: 더 이상 필요 하지 않 은 CRITICALSECTION 변수
void WINAPI EnterCriticalSection(
  _Inout_ LPCRITICAL_SECTION lpCriticalSection
);

매개 변수 1: 잠 겨 있 는 변 수 를 가리 키 며 스 레 드 가 들 어 갈 때 이 관문 을 통과 해 야 합 니 다.
void WINAPI LeaveCriticalSection(
  _Inout_ LPCRITICAL_SECTION lpCriticalSection
);

인자 1: 잠 금 이 해 제 될 변 수 를 가리 키 는 중
경고: critical section 에서 sleep () 또는 그 어떠한 Wait... () API 함 수 를 호출 하지 마 십시오. critical section 은 핵심 대상 이 아니 기 때문에 critical section 에 들 어간 스 레 드 를 끊 고 Leave Critical Section () 을 호출 하지 않 으 면 시스템 에서 이 critical section 을 제거 할 방법 이 없습니다.이러한 기능 이 필요 하 다 면 mutex 를 사용 해 야 합 니 다.
DeadLock/ The Deadly Embrace
쌍방 이 모두 상대방 이 필요 로 하 는 것 을 쥐 고 있 을 때 이런 상황 을 자물쇠 라 고 한다.
 void SwapLists(List* list, List* list2){
    List * tmp_list;
    EnterCriticalSection(list1->critical_sec);
    EnterCriticalSection(list2->critical_sec);
    tmp->list = list1->head;
    list1->head = list2->head;
    list2->head = tmp->list;
    LeaveCriticalSection(list1->critical_sec);
    LeaveCriticalSection(list2->critical_sec);
}

Mutex
먼저 Mutex 와 Critical Section 의 차 이 를 이야기 합 니 다.
  • 가지 고 있 지 않 은 mutex 를 잠 그 는 것 은 가지 고 있 지 않 은 critical section 을 잠 그 는 것 보다 거의 100 배의 시간 이 걸린다. critical
  • section 은 user mode 에서 만 완성 할 수 있 습 니 다.Mutexes 는 프로 세 스 를 뛰 어 넘 을 수 있 습 니 다. Critical section 은 같은 프로 세 스에 서 만 사용 할 수 있 습 니 다
  • Mutex 를 기다 릴 때 기다 리 는 시간 을 지정 할 수 있 으 며, Critical Section 을 기다 리 면 안 됩 니 다.

  • 상호 배척 기 를 만들다
    HANDLE WINAPI CreateMutex(
      _In_opt_ LPSECURITY_ATTRIBUTES lpMutexAttributes,
      _In_     BOOL                  bInitialOwner,
      _In_opt_ LPCTSTR               lpName
    );

    매개 변수 1: 보안 속성, NULL 은 기본 속성 매개 변 수 를 사용 합 니 다 2: CreateMutex 라 는 함 수 를 호출 하 는 스 레 드 는 mutex 를 동시에 가지 고 있 습 니 다. 이 값 은 true 매개 변수 3: mutex 의 이름 으로 설정 되 어 있 습 니 다. 이름 은 문자열 입 니 다. 모든 프로 세 스 와 스 레 드 는 이 이름 으로 값 을 되 돌 릴 수 있 습 니 다. handle 을 성공 적 으로 되 돌 릴 수 있 습 니 다. 그렇지 않 으 면 NULL 로 돌아 갑 니 다. GetLa실패 정 보 를 얻 습 니 다. 예 를 들 어 지정 한 mutex 이름 이 이미 존재 하면 전 송 됩 니 다 ERROR_ALREADY_EXISTS상호 배척 기 를 켜다
    mutex 가 생 성 되 고 이름 이 있다 면 다른 프로 세 스 와 스 레 드 는 이 이름 에 따라 그 mutex 를 열 수 있 습 니 다.
    HANDLE WINAPI OpenMutex(
      _In_ DWORD   dwDesiredAccess,
      _In_ BOOL    bInheritHandle,
      _In_ LPCTSTR lpName
    );

    인자 2: 이 값 이 TRUE 인 경우, 이 프로 세 스에 의 해 생 성 된 프로 세 스 는 핸들 을 상속 합 니 다. 그렇지 않 으 면 프로 세 스 는 이 핸들 을 상속 하지 않 습 니 다.
    여기 상태 에 대하 여:
    mutex 가 있 는 스 레 드 가 없고 Wait... () 로 이 mutex 를 기다 리 는 스 레 드 가 있 으 면 이 mutex 는 일시 적 으로 자극 상태 가 나타 나 Wait.. () 를 되 돌려 주 고 Mutex 는 즉시 비 자극 상태 로 변 합 니 다. 이 Mutex 를 얻 은 스 레 드 가 ReleaseMutex () 를 호출 하여 이 mutex 를 방출 하 는 것 을 알 고 있 습 니 다.
    버 려 진 Mutex
    만약 에 하나의 스 레 드 가 mutex 를 가지 고 있 는데 끝 날 때 까지 ReleaseMutex 를 호출 하지 않 으 면 mutex 는 파괴 되 지 않 고 다음 에 기다 리 는 스 레 드 는 WAIT_ABANDONED_0 로 알려 집 니 다. 선형 이 ExitThread () 로 끝나 거나 끊 어서 끝 날 때 까지 이러한 상황 이 존재 합 니 다.다른 스 레 드 가 WaitForMultiple Objects () 로 이 mutex 를 기다 리 면 이 함수 도 되 돌아 갑 니 다. 전송 값 은 다음 과 같 습 니 다. WAIT_ABANDONED_0 ~ WAIT_ABANDONED_0+N-1자물쇠
    철학 자 들 의 식사 문제 에서 그들 은 다 먹 기 전에 젓가락 을 내 려 놓 고 싶 지 않 지만 젓가락 한 켤레 가 있어 야 먹 기 시작 할 수 있다. 철학 자 들 이 한 번 에 젓가락 하 나 를 얻 도록 허락 한다 면 모든 철학 자 들 이 왼손 젓가락 을 잡 았 을 수도 있다. 이때 그들 은 오른손 젓가락 을 잡 을 수 없다. 오른손 에 있 는 철학 자 들 이 양보 하지 않 기 때문이다.만약 우리 가 프로그램 을 수정 하면 철학 자 에 게 한 번 에 두 젓가락 을 기다 리 게 한다. 프로그램 코드 는 이렇게:
    WaitForMultipleObjects(2,myChopsticks,TRUE,INFINITE);

    한 쌍 의 젓가락 이 있 을 때 만 젓가락 을 들 고 자물쇠 가 생기 지 않 는 다 는 것 이다.
    위의 코드 수정
      void swapLists(struct List * list ,struct List * list2){
        struct List * tmp_list;
        HANDLE arrhandles[2];
        arrhandles[0] = list1->hMutex;
        arrhandles[1] = list2->hMutex;
        WaitForMultipleObjects(2,arrhandles,TRUE,INFINITE);
        tmp->list = list1->head;
        list1->head = list2->head;
        ReleaseMutex(arrhandles[0]);
        ReleaseMutex(arrhandles[1]);
        }

    Semaphores
    mutex 는 semaphore 의 퇴화 입 니 다. 만약 에 semaphore 를 만 들 고 최대 치 를 1 로 한다 면 그것 은 mutex 입 니 다. mutex 는 이 로 인해 binary semaphore 라 고도 부 릅 니 다.
    신호 발생 량
    HANDLE WINAPI CreateSemaphore(
      _In_opt_ LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,
      _In_     LONG                  lInitialCount,
      _In_     LONG                  lMaximumCount,
      _In_opt_ LPCTSTR               lpName
    );

    매개 변수 1: 보안 속성 매개 변수 2: semaphore 초기 값 은 0 보다 크 거나 같 아야 합 니 다. lMaximumCount 매개 변수 3: Semaphore 최대 값 보다 작 아야 합 니 다. 즉, 같은 시간 에 Semaphore 의 최대 매개 변수 4: Semaphore 이름 을 잠 글 수 있 습 니 다. 모든 스 레 드 는 이 이름 에 따라 이 Semaphore 를 사용 할 수 있 습 니 다. NULL 은 이름 이 없 음 을 표시 합 니 다.
    잠 금 가 져 오기
    잠 금 동작 (Wait... () 호출 에 성공 할 때마다 semaphore 의 현재 값 은 1 감소 합 니 다. 잠 금 에 성공 하면 소유권 을 가지 지 않 습 니 다.
    잠 금 해제
    BOOL WINAPI ReleaseSemaphore(
      _In_      HANDLE hSemaphore,
      _In_      LONG   lReleaseCount,
      _Out_opt_ LPLONG lpPreviousCount
    );

    매개 변수 1: Semaphore 의 handle 매개 변수 2: Semaphore 현재 값 의 증가 액 은 마이너스 또는 0 매개 변수 3: Semaphore 원래 의 현재 값 으로 전송 할 수 없습니다. 순간 값 입 니 다. IReleaseCount + * lpPrevious Count 를 semaphore 의 현재 값 으로 사용 할 수 없습니다. 다른 스 레 드 가 semaphore 의 값 을 바 꾸 었 을 수 있 기 때 문 입 니 다.
    이벤트 (이벤트 개체)
    Win 32 에서 가장 탄력 적 인 동기 화 체 제 는 바로 이벤트 대상 이 고 이벤트 대상 은 핵심 대상 으로 프로그램 을 통 해 자극 상태 와 자극 되 지 않 은 상태 로 제어 합 니 다.이벤트 대상 은 다양한 유형의 고급 I / O 작업 에 사 용 됩 니 다.
    이벤트 대상 생 성
    HANDLE WINAPI CreateEvent(
      _In_opt_ LPSECURITY_ATTRIBUTES lpEventAttributes,
      _In_     BOOL                  bManualReset,
      _In_     BOOL                  bInitialState,
      _In_opt_ LPCTSTR               lpName
    );

    매개 변수 1: 보안 속성 매개 변수 2: FALSE 라면 이 이벤트 가 자극 상태 로 변 한 후에 자동 으로 비 자극 상태 로 변 합 니 다. True 로 표시 되면 자동 으로 리 셋 되 지 않 습 니 다. 프로그램 에서 ResetEvent () 를 호출 해 야 비 자극 상태 매개 변수 로 변 할 수 있 습 니 다. 3: true 라면 이 이벤트 가 처음에 자극 상태 에 있 었 음 을 나타 냅 니 다. false 라면...처음에는 비 자극 적 매개 변수 4: event 대상 의 이름 을 표시 합 니 다.
    BOOL WINAPI SetEvent(
      _In_ HANDLE hEvent
    );

    대상 을 자극 상태 로 설정 합 니 다.
    BOOL WINAPI ResetEvent(
      _In_ HANDLE hEvent
    );

    대상 을 비 자극 상태 로 설정 하 다.
    BOOL WINAPI PulseEvent(
      _In_ HANDLE hEvent
    );

    manual reset 이벤트 라면 이벤트 대상 을 자극 상태 로 설정 하고 대기 중인 스 레 드 를 깨 운 다음 에 이 벤트 를 비 자극 상태 로 복원 합 니 다. auto reset 이벤트 라면 이벤트 대상 을 자극 상태 로 설정 하고 대기 중인 라인 을 깨 운 다음 에 이 벤트 를 비 자극 상태 로 복원 합 니 다.
    autoReset 이벤트 대상 에 setEvent () 나 PulseEvent () 를 호출 하면 그 때 는 스 레 드 가 기다 리 지 않 고 이벤트 가 실 종 됩 니 다. 다시 말 하면 스 레 드 가 기다 리 고 있 지 않 으 면 이벤트 가 저장 되 지 않 습 니 다.
    여기 서 잠 금 상태 가 존재 할 수 있 습 니 다. receiver 스 레 드 는 대기 열 에 문자 가 있 는 지 확인 합 니 다. 이때 context switch 가 발생 하여 sender 스 레 드 로 전환 합 니 다. 이벤트 대상 에 대해 Pulse 작업 을 합 니 다. 이때 context switch 가 발생 하여 receiver 스 레 드 로 돌아 가 wait ForSingleObject () 를 호출 하여 이벤트 대상 을 기다 리 고 있 습 니 다.이 동작 은 sender 스 레 드 가 이 벤트 를 자극 한 후에 발생 하기 때문에 이 벤트 는 잃 어 버 릴 수 있 습 니 다. 그래서 receiver 는 영원히 깨 어 나 지 않 고 프로그램 은 잠 겨 있 는 상태 로 들 어 갑 니 다.
    Interlocked Variables
    이것 은 동기 화 체제 의 가장 간단 한 유형 으로 표준 32 비트 변 수 를 조작 합 니 다. 그들 은 특정한 변수 에 대한 액세스 작업 만 순서대로 할 수 있 습 니 다.사실은 원자 조작 이다. 예 를 들 어:
    LONG __cdecl InterlockedIncrement(
      _Inout_ LONG volatile *Addend
    );

    Decrements (decreases by one) the value of the specified 32-bit variable as an atomic operation.
    LONG __cdecl InterlockedDecrement(
      _Inout_ LONG volatile *Addend
    );

    매개 변수 1: 32 비트 변수의 주 소 는 이 변수 가 점점 줄 어 든 다음 에 결 과 를 0 과 비교 해 야 합 니 다. 이 주 소 는 롱 워드 가 0 과 같 으 면 0 을 되 돌려 주 고 0 보다 크 면 플러스 를 되 돌려 주 며 0 보다 작 으 면 마이너스 로 되 돌려 주어 야 합 니 다.
    LONG __cdecl InterlockedExchange(
      _Inout_ LONG volatile *Target,
      _In_    LONG          Value
    );

    interlocked.. () spin - lock (자전 자물쇠 라 고도 부 릅 니 다. 스 레 드 는 busy - wait - loop 방식 으로 자 물 쇠 를 가 져 옵 니 다. 언제든지 하나의 스 레 드 만 자 물 쇠 를 얻 을 수 있 고 다른 스 레 드 는 자 물 쇠 를 얻 을 때 까지 기다 리 며 spinlock 은 스 레 드 의 상태 전환 을 초래 하지 않 습 니 다) 그러면 동기 화 체제 일 뿐 입 니 다.이것 은 주로 계 수 를 인용 하 는 데 사 용 됩 니 다. critical section 이나 mutex 같은 것 을 사용 하지 않 아 도 됩 니 다. 왜냐하면 32 비트 변수의 액세스 작업 은 2 ~ 3 개의 기계 명령 만 필요 하기 때 문 입 니 다.
    자료 출처: Win 32 다 중 스 레 드 프로 그래 밍

    좋은 웹페이지 즐겨찾기