Lab 8 Guide: 멀티스레딩 예제 2 * Critical Section을 이용한 멀티스레딩 동기화 (교재 15장, 828-832쪽)
실습 목적 및 장비 실습 목적 장비: PC, 윈도우 운영체제, Visual Studio (VC++ 6.0) 멀티스레드 프로그램의 동기화 처리 방법 Critical Section의 표현과 이용 방법 장비: PC, 윈도우 운영체제, Visual Studio (VC++ 6.0)
1. Critical Section을 이용한 통신 프로그램 예제 프로그램 개요 다이얼로그 기반 애플리케이션 Stack 클래스 구현 그래픽 기능을 이용하여 스택 상태 그림 두 개의 스레드를 생성 스택에 Push()한 후 스택 다시 그림 스택에서 Poph()한 후 스택 다시 그림 Critical Section을 사용하여 두 스레드에 대한 동기화 표현 두 개의 체크박스 Disabled 속성 m_ctrlPush, m_ctrlPop 변수 연결 실행 파일(http://cs.sookmyung.ac.kr/class/06395/Lab/CriticalSectionTest0.exe)
Critical Section을 이용한 통신 프로그램 예제 Stack의 구현 (Stack.h) #define STACK_SIZE 10 class Stack { public: int Pop(); void Push (); BOOL IsFull(); BOOL IsEmpty(); int Stack::operator[](int i); Stack(); virtual ~Stack(); private: int * data; int top; };
Critical Section을 이용한 통신 프로그램 예제 Stack의 구현 (Stack.cpp) #include <stdafx.h> // for BOOL #include “Stack.h” Stack::Stack() { top = 0; data = new int[STACK_SIZE]; for (int i = 0; i < STACK_SIZE; i++) data[i] = -1; } Stack::~Stack() { delete [] data; BOOL Stack::IsEmpty() { return top == 0; BOOL Stack::IsFull() { return top == STACK_SIZE;
void Stack::Push() { if (!IsFull()) data[top] = top, top++; } int Stack::Pop() { if (!IsEmpty()) { int x = data[top]; data[top] = -1; top--; return x; } else return -1; int Stack::operator[](int i) { return data[i];
Critical Section을 이용한 통신 프로그램 예제 동기화 객체 생성, 스레드 함수 포로토타입 선언 (in “CriticalSectionTestDlg.cpp”) 두 개의 Thread 생성 #include <afxmt.h> CCriticalSection g_cs; UINT ThreadForPush(LPVOID pParam); UINT ThreadForPop(LPVOID pParam); BOOL CCriticalSectionTestDlg::OnInitDialog() { … AfxBeginThread(ThreadForPush, this); AfxBeginThread(ThreadForPop, this); }
Critical Section을 이용한 통신 프로그램 예제 전역 변수로 Stack 인스턴스 정의, 스택 상태를 그리는 함수 작성 #include "Stack.h" Stack stack; void CCriticalSectionTestDlg::DrawStack() { static CClientDC dc(this); CRect r; GetClientRect(&r); r.InflateRect(-100, -20); CPoint br = r.BottomRight(); CPoint tl = r.TopLeft(); for (int i = 0; i < STACK_SIZE; i++) { CRect rect(tl.x, ((i + 1) * tl.y + (STACK_SIZE - i - 1) * br.y) / STACK_SIZE, br.x, (i * tl.y + (STACK_SIZE - i) * br.y) / STACK_SIZE); CBrush *pBrush = (CBrush *) dc.SelectStockObject(GRAY_BRUSH); if (stack[i] == -1) pBrush = (CBrush *) dc.SelectStockObject(WHITE_BRUSH); Sleep(20); dc.FillRect (&rect, pBrush); dc.Rectangle(&rect); }
Critical Section을 이용한 통신 프로그램 예제 스레드 함수 정의 UINT ThreadForPush(LPVOID pParam) { CCriticalSectionTestDlg *pWnd = (CCriticalSectionTestDlg *) pParam; while (1) { Sleep (200 + rand()%1000); g_cs.Lock(); if (!stack.IsFull()) { stack.Push(); pWnd->m_ctrlPush.SetCheck(1); pWnd->m_ctrlPop.SetCheck(0); pWnd->DrawStack(); } g_cs.Unlock(); return 0;
Critical Section을 이용한 통신 프로그램 예제 스레드 함수 정의 UINT ThreadForPop(LPVOID pParam) { CCriticalSectionTestDlg *pWnd = (CCriticalSectionTestDlg *) pParam; while (1) { Sleep (300 + rand()%1000); g_cs.Lock(); if (!stack.IsEmpty()) { stack.Pop(); pWnd->m_ctrlPush.SetCheck(0); pWnd->m_ctrlPop.SetCheck(1); pWnd->DrawStack(); } g_cs.Unlock(); return 0;
추가 실험 및 보고서 작성 요령 추가 실험 동기화 객체에 대한 Lock(), Unlock() 호출 부분을 주석 처리한 다음 컴파일하여 실행 결과 관찰 보고서 Dialog 클래스 부분의 프로그램 소스 프로그램 설명 (AppWizard에 의해 생성된 부분은 제외) 위의 추가 실험 결과 분석