티스토리 뷰
책 : 뇌를 자극하는 윈도우즈 시스템 프로그래밍
1 ) 이름있는 뮤텍스(NamedMutex) 동기화
- 원래 선언된 Mutex는 하나의 프로세스에서 내부 쓰레드들만 사용할 수 있는데, 이름있는 뮤텍스를 사용하면 다른 프로세스들이 그 뮤텍스를 사용할 수 있습니다. 코드를 예시로 확인해 보겠습니다.
if 1 -> 이름있는 뮤텍스를 생성하는 코드
else -> 외부 프로세스에서 뮤텍스 접근하여 사용하는 코드
예제
더보기
#include <stdio.h>
#include <windows.h>
#include <process.h>
#include <tchar.h>
HANDLE hMutex;
DWORD dwWaitResult;
void ProcessBaseCriticalSection()
{
dwWaitResult = WaitForSingleObject(hMutex, INFINITE);
switch (dwWaitResult)
{
// 쓰레드가 뮤텍스를 소유하였다.
case WAIT_OBJECT_0:
_tprintf(_T ("thread got mutex ! \n") );
break;
// time-out 발생하였다.
case WAIT_TIMEOUT:
_tprintf(_T ("timer expired ! \n") );
return;
// 뮤텍스 반환이 적절이 이뤄지지 않았다.
case WAIT_ABANDONED:
return;
}
for(DWORD i=0; i<5; i++)
{
_tprintf( _T("Thread Running ! \n") );
Sleep(5000);
}
ReleaseMutex(hMutex);
}
int _tmain(int argc, TCHAR* argv[])
{
#if 1
hMutex = CreateMutex(
NULL,
FALSE,
_T("NamedMutex")
);
#else
hMutex = OpenMutex(
MUTEX_ALL_ACCESS,
FALSE,
_T("NamedMutex")
);
#endif
if (hMutex == NULL)
{
_tprintf(_T("CreateMutex error: %d\n"), GetLastError());
return -1;
}
ProcessBaseCriticalSection();
CloseHandle(hMutex);
return 0;
}
2 ) WAIT_ABANDONED
- 이건 WaitSingleObject에서 리턴되는 값 중 하나인데, Mutex를 소유하는 쓰레드가 종료하기 전에 소유권을 반환 해줘야 하는데 그렇지 않고 종료하게 되면, Windows에서 이러한 상황을 파악하여 대신 반환해 줍니다. 그럴때 리턴되는 값으로 아래의 코드를 통해서 확인해볼 수 있습니다.
예제
더보기
#include <stdio.h>
#include <windows.h>
#include <process.h>
#include <tchar.h>
HANDLE hMutex;
LONG gTotalCount = 0;
unsigned int WINAPI IncreaseCountOne(LPVOID lpParm) {
WaitForSingleObject(hMutex, INFINITE);
gTotalCount++;
//Mutex 반환 없이 종료
return 0;
}
unsigned int WINAPI IncreaseCountTwo(LPVOID lpParm) {
DWORD dwWaitResult = 0;
dwWaitResult = WaitForSingleObject(hMutex, INFINITE);
switch (dwWaitResult) {
case WAIT_OBJECT_0:
ReleaseMutex(hMutex);
break;
case WAIT_ABANDONED:
_tprintf(_T("WAIT_ABANDONED \n"));
break;
}
gTotalCount++;
ReleaseMutex(hMutex);
return 0;
}
int _tmain(int argc, TCHAR* argv[])
{
DWORD dwThreadIDOne;
HANDLE hThreadOne;
HANDLE hThreadTwo;
hMutex = CreateMutex(NULL, FALSE, NULL);
if (hMutex == NULL)
_tprintf(_T("Create Mutex error : %d\n"), GetLastError());
//무례한 쓰레드
hThreadOne = (HANDLE)_beginthreadex(NULL, 0, IncreaseCountOne, NULL,
0, NULL);
hThreadTwo = (HANDLE)_beginthreadex(NULL, 0, IncreaseCountTwo, NULL,
CREATE_SUSPENDED, NULL);
Sleep(1000);
ResumeThread(hThreadTwo);
WaitForSingleObject(hThreadTwo, INFINITE);
_tprintf(_T("total count : %d\n"), gTotalCount);
CloseHandle(hThreadOne);
CloseHandle(hThreadTwo);
CloseHandle(hMutex);
return 0;
}
'서버 공부 > 시스템 프로그래밍' 카테고리의 다른 글
리눅스 파이프 통신과 좀비 프로세스 잡기 (0) | 2022.10.12 |
---|---|
메모리 관리 - 힙(Heap) 컨트롤 (0) | 2022.07.29 |
쓰레드 동기화 기법 - 커널 모드 동기화 (0) | 2022.07.28 |
쓰레드 동기화 기법 - 유저 모드 동기화 (0) | 2022.07.28 |
쓰레드 구현 모델 (0) | 2022.07.28 |
댓글