본문 바로가기
프로그래밍/Windows

쓰레드 동기화와 WAIT_ABANDONED

by 즉흥 2014. 6. 2.
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

댓글