mfc_Thread_2 - 8BitsCoding/RobotMentor GitHub Wiki
Thread๋ฅผ ์ฌ๋ฌ๊ฐ ๋ง๋ค์ด์ ํ๋ ฅํ๋ฉฐ ์ฐ๋ ๋ฒ์ ๋ํด ๊ณ ๋ฏผ
์ฐ์ ์์๋ฅผ ๊ตฌํ๋ ํจ์๋ฅผ ํ๋ ์์ฑํด๋ณธ๋ค.
int IsPrime(int a_num)
{
int i;
for(i = 2; i < a_num; i++)
{
if(a_num % i == 0) return 0;
}
return 1;
}
2~200000 ์ฌ์ด์ ์์๋ฅผ ๋ชจ๋ ํฉ์ฐํ๋ Thread๋ฅผ ์์ฑํด ๋ณด์.
DWORD WINAPI InsertItemToList(void * ap_data)
{
ThreadData * p_data = (ThreadData *)ap_data;
CString str;
int index;
__int64 sum = 0;
int start_tick = GetTickCount();
for(unsigned int i = 2; i < 200000; i++) {
if(WaitForSingleObject(p_data->h_kill_event,0) == WAIT_OBJECT_0) break;
if(IsPrime(i)) sum += i;
if(!(i%100000)) {
str.Format(L"์์
์งํ์ค %d๊น์ง ์ฒดํฌํจ!");
index = p_data->p_list_box->InsertString(-1, str);
p_data->p_list_box_SetCurSel(index);
}
}
str.Format(L"2~200000๊น์ง ์์์ ํฉ์ %lld์ด๋ค. (%dms)", sum, GetTickCount() - start_tick);
index = p_data->p_list_box->InsertString(-1, str);
p_data->p_list_box_SetCurSel(index);
CloseHandle(p_data->h_thread);
p_data->h_thread = NULL;
return 0;
}
๋ฒํผ์ ๋๋ฅผ๋๋ง๋ค Thread๋ฅผ ๋ง๋ค๊ฒ ๋ณ๊ฒฝํด๋ณด์.
// Dlg.h
struct ThreadData
{
HWND h_wnd; // ๋ํ์์์ Handle
unsigned int step; //
CListBox * p_list_box;
HANDLE h_kill_event;
HANDLE h_thread;
DWORD thread_id;
};
// Dlg.cpp
private:
unsigned int m_step = 200000;
// Thread ์์ฑ ๋ฒํผ
ThreadData * p = new ThreadData;
p->h_wnd = m_hWnd;
p->step = m_stop;
p->p_list_box = &m_data_list;
p->h_kill_event = CreateEvent(NULL, 1, 0, NULL);
p->h_thread = CreateThread(NULL, 0, InsertItemToList, p, 0, &p->thread_id);
CString str;
str.Format(L"%08x : %u ๊น์ง ํฉ์ฐ", p->thread_id, p->step);
int index = m_thread_list.InsertString(-1, str);
m_thread_list.SetItemDataPtr(index, p);
m_step *= m_step;
DWORD WINAPI InsertItemToList(void * ap_data)
{
ThreadData * p_data = (ThreadData *)ap_data;
CString str;
int index;
str.Format(L"[%08x] ์์
์ ์์ํฉ๋๋ค!", p_data->thread_id);
p_data->p_list_box->SetCurSel(index);
__int64 sum = 0, kill_flag = 0;
int start_tick = GetTickCount();
unsigned int i;
for(i = 2; i < 200000; i++) {
if(WaitForSingleObject(p_data->h_kill_event,0) == WAIT_OBJECT_0) {
str.Format(L"[%08x] ์์
์ค๋จ ์ฒดํฌํจ!", p_data->thread_id);
index = p_data->p_list_box->InsertString(-1, str);
kill_flag = 1;
break;
}
if(IsPrime(i)) sum += i;
if(!(i%100000)) {
str.Format(L"[%08x] ์์
์งํ์ค %d๊น์ง ์ฒดํฌํจ!", p_data->thread_id);
index = p_data->p_list_box->InsertString(-1, str);
p_data->p_list_box_SetCurSel(index);
}
}
str.Format(L"[%08x] 2~%u๊น์ง ์์์ ํฉ์ %lld์ด๋ค. (%dms)", p_data->thread_id, i, sum, GetTickCount() - start_tick);
index = p_data->p_list_box->InsertString(-1, str);
p_data->p_list_box_SetCurSel(index);
str.Format(L"[%08x] ์์
์ ์ค๋จํฉ๋๋ค!", p_data->thread_id);
p_data->p_list_box->SetCurSel(index);
CloseHandle(p_data->h_thread);
if(WaitForSingleObject(p_data->h_kill_event, 0) == WAIT_OBJECT_0) kill_flag= 1;
::PostMessage(p_data->h_wnd, 27001, kill_flag, (LPARAM)p_data);
return 0;
}
์ฝ๋์ค๋ช
(์ฐธ๊ณ ) LPARAM, WPARAM
LPARAM : ์ ํต์ ์ผ๋ก 4 bytes ์ฃผ์๊ฐ์ ๋ณดํต ๋๊ฒจ์ค๋ค.
WPARAM : ์ต๊ทผ์๋ 4 bytes ๊ฐ ๋์์ผ๋ ์์ ์ 2 bytes๋ก ๋ณดํต ์ฃผ์๊ฐ์ ๋ฃ์ง ์๊ณ char, byte๋ฑ์ ๋ฃ์์.
::PostMessage(p_data->h_wnd, 27001, kill_flag, (LPARAM)p_data);
: ๋ถ๋ชจ ๋ค์ด์ผ๋ก๊ทธ(p_data->h_wnd)๋ก ๋ฉ์์ง(27001)๋ฅผ ๋ณด๋ธ๋ค. ๋ฉ์์ง์ WPARAM = kill_flag(์ด์ฉ์๊ฐ ์ฃฝ์ธ๊ฒ์ธ์ง ์์ฐ์ค๋ฝ๊ฒ ์ฃฝ์๊ฒ์ธ์ง), LPARAM = p_data์ ์ฃผ์๊ฐ.
if(WaitForSingleObject(p_data->h_kill_event, 0) == WAIT_OBJECT_0) kill_flag= 1;
: ๋ง์ง๋ง์ ์ด ํ ์ค์ด ๋ ๋ค์ด๊ฐ๋ ์ด์ ๋?? -> 200000๋ฒ๊น์ง ๋๋๋ฐ 199999๊น์ง ๋๋ ์๊ฐ์ ์ด์ฉ์๊ฐ Thread์ข ๋ฃ๋ฅผ ๋๋ฅด๋ฉด kill_flag๊ฐ 0์ธ์ฑ๋ก ๋๋๋ฒ๋ฆฐ๋ค. ๊ทธ ์ํฉ์ ๋ฐฉ์งํ๊ธฐ ์ํด์.
// thread ์ ํ ์ข
๋ฃ
int index = m_thread_list.GetCurSel();
if(LB_ERR != index)
{
ThreadData* p = (ThreadData*)m_thread_list.GetItemDataPtr(index);
if(p->h_thread != NULL) {
SetEvent(p->h_kill_event);
MSG msg;
while(p->h_thread != NULL) {
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
delete p;
}
}
else {
}
์ฝ๋์ค๋ช
PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)
: ๋ฉ์์ง๊ฐ ์์ผ๋ฉด ๋์ ์์ผ๋ฉด ๊ทธ๋ฅ ๋์ด๊ฐ, RM_REMOVE : ๋ฉ์์ง๋ฅผ ๋ณต์ฌํ์ง ์๊ณ ๊บผ๋ด์ด๊ธฐ์กด
GetMessage()
์์ ์ฐจ์ด์ ์ ๋ฉ์์ง๊ฐ ์๋์ง ์๋์ง ํ์ธํ๋ค๋ ์ ์ด๋ค.GetMessage๋ฅผ ์ฐ๋ฉด ๋ฉ์์ง๋ฅผ ๋ฌดํ์ ๊ธฐ๋ค๋ฆฌ๋ฉฐ ๋ฐ๋๋ฝ์ ๊ฑธ๋ฆด ์ ์๋ค.
์ฌ์ฉ์ ์ง์ ๋ฉ์์ง(27001) ์ถ๊ฐ
ํด๋์ค ๋ง๋ฒ์ฌ(Shift+Ctrl+x) -> ์ฌ์ฉ์ ์ง์ ๋ฉ์์ง ์ถ๊ฐ -> 27001
// On27001
ThreadData * p = (ThreadData *)lParam;
int count = m_thread_list.GetCount();
for(int i = 0; i < count; i++) {
if(m_thread_list.GetItemDataPtr(i) == p) {
m_thread_list.DeleteString(i);
CloseHandle(p->h_kill_event);
if(wParam == 0) delete p;
else p->thread = NULL;
break;
}
}
// OnDestroy()
OnBtnAllStop();
// ๋ชจ๋ Thread ์ข
๋ฃ ๋ฒํผ (OnBtnAllStop())
ThreadData * p;
int count = m_thread_list.GetCount();
for(int i = 0; i < count; i++){
p = (ThreadData*) m_thread_list.GetItemDataPtr(i);
SetEvent(p->h_kill_event);
}
CString str;
str.Format(L"Thread %d๊ฐ๋ฅผ ์ข
๋ฃํฉ๋๋ค.", count);
int index = m_data_list.InsertString(-1, str);
m_data_list.SetCurSel(index);
MSG msg;
while(count) {
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
if(msg.message == 27001) {
count--;
msg.wParam = 0; // kill_flag๋ฅผ 1๋ก ๋ฐ๊พธ๋ฉด ์ฌ๊ธฐ์ delete๋ฅผ ํ์ง ์์๋ ๋๋ค.
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
index = m_data_list.InsertString(-1, L"๋ชจ๋ Thread๊ฐ ์ข
๋ฃ๋์์ต๋๋ค.!");
m_data_list.SetCurSel(index);