티스토리 뷰
MFC 스레드 동기화 - 뮤텍스 (Mutex, Mutual Exclusion)
임계 영역과 동일한 기능을 한다.
공유 리소스를 접근하는 다수의 스레드가 있을때 오직 하나의 스레드만 접근할 수 있도록 한다.
커널 모드로 동작하기 때문에 속도는 느리지만 여러 프로세스에 속한 스레드간의 동기화에 사용한다.
Lock/unlock 으로 제어
특징>
Lock() 호출에 성공한 스레드가 해당 뮤텍스 객체를 소유한다는 것이고, 뮤텍스를 소유한 스레드만이 Unlock() 을 호출하여 자신의 소유권을 포기할 수 있다.
뮤텍스 생성 함수
CMutex::CMutex(BOOL bInitiallyOwn = FALSE, LPCTSTR lpszName = NULL, LPSECURITY_ATTRIBUTES lpsaAttribute = NULL);
- bInitiallyOwn
TRUE 면 뮤텍스를 생성한 스레드가 소유자가 된다.
- lpszName
뮤텍스 이름, NULL이면 이름없는(Anonynous) 뮤텍스가 된다.
서로 다른 프로세스에 존재하는 스레드가 뮤텍스를 이용하여 스레드 동기화를 하려면 동일한 이름을 가진 뮤텍스를 접근해야 한다.
- lpsaAttribute
보안 설명자와 핸들 상속에 관련된 구조체로 특별한 경우가 아니면 기본값인 NULL 을 사용한다.
다이얼로그 베이스 프로젝트 만들고, 리스트 컨트롤의 SORT 속성은 False 로 한다.
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 |
UINT MyThread(LPVOID pParam)
{
CMFCApplication7Dlg* ptr = (CMFCApplication7Dlg*)pParam;
CString str;
for (int i = 0; i < 100; i++)
{
str.Format(L"%d", i);
ptr->m_list.AddString(str);
::Sleep(10);
}
return 0;
}
class CMFCApplication7Dlg : public CDialogEx
{
...
public:
afx_msg void OnBnClickedStart();
CListBox m_list;
};
void CMFCApplication7Dlg::OnBnClickedStart()
{
m_list.ResetContent();
AfxBeginThread(MyThread, this);
AfxBeginThread(MyThread, this);
AfxBeginThread(MyThread, this);
} |
cs |
스레드가 동시 실행되니 숫자들이 000, 111 로 추가된다.
<뮤택스 적용 후>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 |
#include <afxmt.h>
CMutex g_mutex(FALSE, NULL); // 전역 변수
UINT MyThread(LPVOID pParam)
{
CMFCApplication7Dlg* ptr = (CMFCApplication7Dlg*)pParam;
CString str;
g_mutex.Lock(); // 뮤텍스 적용
for (int i = 0; i < 100; i++)
{
str.Format(L"%d", i);
ptr->m_list.AddString(str);
::Sleep(10);
}
g_mutex.Unlock(); // 뮤텍스 해제
return 0;
} |
cs |
뮤텍스 적용 후 스레드가 순서대로 시작된다.