728x90
반응형
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | #include<cstdio> #include<cstdlib> #include<Windows.h> #include<process.h> LONG gTotalCount = 0; HANDLE hMutex; unsigned int WINAPI IncreaseCountOne(LPVOID lpParam){ WaitForSingleObject(hMutex, INFINITE); gTotalCount++; puts("1st thread"); //ReleaseMutex(hMutex); return 0; } unsigned int WINAPI IncreaseCountTwo(LPVOID lpParam){ DWORD dwWaitResult = 0; dwWaitResult = WaitForSingleObject(hMutex, INFINITE); switch (dwWaitResult){ case WAIT_OBJECT_0: ReleaseSemaphore(hSemaphore, 1, NULL); break; case WAIT_ABANDONED: printf("wait_abandoned\n"); break; } gTotalCount++; ReleaseMutex(hMutex); return 0; } int main(){ DWORD dwThreadIDOne; DWORD dwThreadIDTwo; HANDLE hThreadOne; HANDLE hThreadTwo; hMutex = CreateMutex(NULL, false, NULL); hThreadOne = (HANDLE)_beginthreadex( NULL, 0, IncreaseCountOne, NULL, 0, NULL); hThreadTwo = (HANDLE)_beginthreadex( NULL, 0, IncreaseCountTwo, NULL, 0, NULL); Sleep(100); ResumeThread(hThreadTwo); WaitForSingleObject(hThreadTwo, INFINITE); printf("total cnt : %d\n", gTotalCount); CloseHandle(hThreadOne); CloseHandle(hThreadTwo); return 0; } |
위는 책에 있던 예제.
뭐냐면 임계영역에 뮤텍스를 하나 걸고, 두 개의 쓰레드를 만든다.
처음 임계영역에 접근했던 쓰레드가 ReleaseMutex() 함수를 실행하지 않고 종료하게 되면,
Windows가 알아서 해당 뮤텍스를 대신 반환(WAIT_ABANDONED)하여주고 이어서 두 번째 쓰레드가 실행할 수 있다는 것이다.
위에는 위 예제의 실행 결과.
뮤텍스는 뮤텍스를 획득한 쓰레드가 해당 뮤텍스를 반환하는 것이 원칙. 획득한 쓰레드만이 해당 뮤텍스를 반환할 수 있다는 것.
어쨋는 나는 세마포어도 위와 같은 문제가 생겼을 때, windows가 해결해주는지 알아봄.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | #include<cstdio> #include<cstdlib> #include<Windows.h> #include<process.h> LONG gTotalCount = 0; HANDLE hSemaphore; unsigned int WINAPI IncreaseCountOne(LPVOID lpParam){ WaitForSingleObject(hSemaphore, INFINITE); gTotalCount++; puts("1st thread"); //ReleaseSemaphore(hSemaphore, 1, NULL); return 0; } unsigned int WINAPI IncreaseCountTwo(LPVOID lpParam){ DWORD dwWaitResult = 0; dwWaitResult = WaitForSingleObject(hSemaphore, INFINITE); switch (dwWaitResult){ case WAIT_OBJECT_0: ReleaseSemaphore(hSemaphore, 1, NULL); break; case WAIT_ABANDONED: printf("wait_abandoned\n"); break; } gTotalCount++; ReleaseSemaphore(hSemaphore, 1, NULL); return 0; } int main(){ DWORD dwThreadIDOne; DWORD dwThreadIDTwo; HANDLE hThreadOne; HANDLE hThreadTwo; hSemaphore = CreateSemaphore(NULL, 1, 1, NULL); hThreadOne = (HANDLE)_beginthreadex( NULL, 0, IncreaseCountOne, NULL, 0, NULL); hThreadTwo = (HANDLE)_beginthreadex( NULL, 0, IncreaseCountTwo, NULL, 0, NULL); Sleep(100); ResumeThread(hThreadTwo); WaitForSingleObject(hThreadTwo, INFINITE); printf("total cnt : %d\n", gTotalCount); CloseHandle(hThreadOne); CloseHandle(hThreadTwo); return 0; } |
뮤텍스를 세마포어로 바꾸고, 세마포어가 지닐 수 있는 쓰레드 개수의 최대 값을 1로 설정함.
실행해봤더니 첫 번째 쓰레드가 세마포어를 반환하지 않아서 이 상태에서 멈춰있다.
해결할라면
ReleaseSemaphore(hSemaphore, 1, NULL);
에 걸려있는 주석을 해제하던가
WaitForSingleObject() 함수에 INFINITE가 아닌 다른 숫자를 넣어서 TIMEOUT이 반환되면 ReleaseSemaphore() 함수를 호출해야겠다.
세마포어는 뮤텍스와는 다르게 세마포어를 획득한 쓰레드가 해당 세마포어를 반환하지 않아도 되니까.
728x90
반응형
'프로그래밍 > Windows' 카테고리의 다른 글
WinAPI 콤보박스 생성 / ComboBox (0) | 2015.06.01 |
---|---|
process list 출력 (2) | 2015.05.20 |
how to create ListView on Visual C++ (0) | 2015.05.20 |
사용자 입력 글자수 제한하기 (0) | 2014.07.04 |
C++ WinForm Frame (0) | 2014.07.04 |
GetExitCodeProcess (0) | 2014.05.25 |
(싱글 더블 와이드) 함수 정리 (0) | 2014.05.25 |
IPC MailSlot 메일 슬롯 (0) | 2014.05.25 |
tchar.h (1) | 2014.05.13 |
사용자 정의 에러 함수 _invalid_parameter_handler (0) | 2014.05.01 |
댓글