티스토리 뷰
쓰레드 동기화
주의점:
1. 쓰레드내에서 쓰레드 생성한 메인쓰레드의 변수를 참조할때는 직접 함수로 참조하지말고, 메시지로 해야한다. - 직접 참조 시 충돌 나는지 '가끔' 디버깅 에러 발생한다.
쓰레드에서 p메인쓰레드->Set변수(값) 혹은 p메인쓰레드->Get변수() 으로 변수 접근하지 말고
SendMessage(p메인쓰레드핸들, 사용자정의메시지, 값, 값) 으로 해야 했다.
2. 메인 쓰레드에서 받은 포인터안의 데이터(문자열 등)를 쓰레드 내에서 while 루프 등 시간이 걸리는 작업을 할때는 포인터 변수로 사용하지 않고 '힙' 이나 '배열' 등 고정 길이로 할당된 변수에 값을 저장해서 사용해야 데이터가 깨지지 않는다.
한 순간에 메모리(임계영역)의 접근을 하나의 쓰레드에서만 접근할 수 있게 제어한다.
1. 임계영역 (Critical Section) - 유저모드 (속도 빠름)
1) CRITICAL_SECTION 변수 선언
2) 초기화 - InitializeCriticalSection() 호출
3) 대기상태로 만듬 - WaitForMultipleObjects()
4) 접근 전에 EnterCriticalSection() 호출해서 다른 쓰레드 접근을 차단
5) 사용이 끝나면 LeaveCriticalSection() 호출해서 다른 쓰레드에서 사용 가능하게 한다.
6) 초기화에서 할당한 리소스를 해제 - DeleteCriticalSection() 호출
만약, 접근해서 1씩 증감하는 경우라면 InterlockedIncrement()/interlockedDecrement() 로 간단하게 만들수 있다.
2. 뮤텍스 (Mutex) - 커널 모드 (속도 느림, 커널모드에서 제공하는 기능 사용 가능)
1) 핸들 선언 - HANDLE hMutex
2) 뮤텍스 생성하고 핸들 저장 - hMutex = CreateMutext()
3) 대기상태로 만듬 - WaitForMultipleObjects()
4) 접근 전에 WaitForSingleObject() 로 다른 스레드 접근 금지 시킨다.
5) 사용이 긑나면 ReleaseMutex() 호출해서 다른 쓰레드에서 사용할 수 있게 한다.
6) 모든 쓰레드가 종료하면 3)번의 대기 상태가 해제된다.
7) CloseHandle(hThread) 로 쓰레드 반환
8) CloseHandle(hMutex) 로 뮤텍스 반환
3. 세마포어 (Semaphore) - 커널 모드 (속도 느림, 커널모드에서 제공하는 기능 사용 가능)
뮤텍스에 카운팅 기능 추가
임계영역에 동시 접근 가능한 수를 카운팅. (10개의 테이블이고 총 10 손님만 받을 수 있는 경우)
1) 핸들 선언 - HANDLE hSemaphore
2) 세마포어 생성하고 핸들 저장 - hSemaphore = CreateSemaphore()
3) 대기상태로 만듬 - WaitForMultipleObjects()
4) 접근 전에 WaitForSingleObject() 로 다른 스레드 접근 금지 시킨다. 이때 카운팅 1 감소.
5) 사용이 긑나면 ReleaseSemaphore() 호출해서 다른 쓰레드에서 사용할 수 있게 한다. 카운팅 1 증가
6) 모든 쓰레드가 종료하면 3)번의 대기 상태가 해제된다.
7) CloseHandle(hThread) 로 쓰레드 반환
8) CloseHandle(hMutex) 로 뮤텍스 반환