mfc_Thread_3 - 8BitsCoding/RobotMentor GitHub Wiki

Thread๊ฐ€ ํŠน์ • ์ž์›์„ ๊ณต์œ ํ•˜๋ฉฐ ์“ฐ๋Š” ์˜ˆ์‹œ

๊ธฐ์กด์— 200000๊ฐœ์”ฉ ์ถ”๊ฐ€๋กœ ์†Œ์ˆ˜๋ฅผ ๊ตฌํ•˜๋˜ ๊ณผ์ •์„

1600000๊ฐœ์˜ ์†Œ์ˆ˜์˜ ํ•ฉ์„ ๊ตฌํ•˜๋Š”๋ฐ 32๊ฐœ์˜ Thread๋ฅผ ์ƒ์„ฑํ•ด์„œ ๊ตฌํ•ด๋ณด์ž.

Thread์˜ ๊ตฌ์„ฑ์€ 32๊ฐœ์˜ Thread๋ฅผ ๊ฐ–๊ณ 

ํ•˜๋‚˜์˜ Thread๋Š” 2, 34, 66 ....

3, 35, 67 .... ์ด๋Ÿฐ์‹์œผ๋กœ 32์”ฉ ๋”ํ•˜๋ฉด์„œ 32๊นŒ์ง€ ์ด 32๊ฐœ์˜ Thread๋ฅผ ์ƒ์„ฑํ•˜๊ฒŒ ๋œ๋‹ค.

๊ทธ๋Ÿฐ๋ฐ Core๊ฐ€ 32๊ฐœ๊ฐ€ ์•„๋‹Œ๋ฐ Thread๋ฅผ 32๊ฐœ๋‚˜ ๋งŒ๋“œ๋Š” ์ด์œ ๋Š”??

2์˜ ๋ฐฐ์ˆ˜์˜ ์†Œ์ˆ˜๋ฅผ ๊ตฌํ•˜๋Š” ๊ณผ์ •์€ ๊ธˆ๋ฐฉ๋๋‚˜๊ธฐ์— 32๊ฐœ๋ฅผ ๋งŒ๋“ ๋‹ค ํ•˜๋”๋ผ๋„ ์ ˆ๋ฐ˜์ด์ƒ์€ ๊ธˆ๋ฐฉ๋๋‚˜๊ธฐ๋•Œ๋ฌธ!

// Dlg.h
struct ThreadData 
{
    HWND h_wnd;
    CListBox* p_list_box;
    HANDLE h_kill_event;
    HANDLE h_thread;
    DWORD thread_id;
    unsigned int start_step, end_step, thread_count;
    __int64* p_sum;
};

private:
    unsigned int m_step = 1600000;
    int m_thread_count = 32;
    __int64 m_sum = 0;              // ๋ชจ๋“  Thread๊ฐ€ ๊ณต์œ ํ•  ์ž์›
    unsigned int m_start_tick;

์‹œ์ž‘๋ฒ„ํŠผ ํด๋ฆญ ์‹œ 32๊ฐœ์˜ Thread ์ƒ์„ฑ

if(m_thread_list.GetCount() > 0) return;

m_sum = 0;
m_start_tick = GetTickCount();

ThreadData * p;

for(int i = 0; i < m_thread_count; i++) {
    p = new ThreadData;
    p->h_wnd = m_hWnd;
    p->start_step = 2 + i;
    p->end_step = m_step;
    p->p_list_box = &m_data_list;
    p->thread_count = m_thread_count;
    p->p_sum = &m_sum;
    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 ~ %u)๊นŒ์ง€ ํ•ฉ์‚ฐ", p->thread_id, p->start_step, p->end_step);
    m_thread_list.InsertString(i, str);
    m_thread_list.SetItemData(i, p);
}
DWORD WINAPI InsertItemToList(void* ap_data)
{
    ThreadData* p_data = (ThreadData*)ap_data;
    CString str;

    int start_tick = GetTickCount(), kill_flag = 0;
    int index;

    unsigned int i ;
    for(i = p_data->start_step; i <= p_data->end_step; i += p_data->thread_count) {
        if(WaitForSingleObject(p_data->h_kill_event, 0) == WAIT_OBJECT_0) {
            kill_flag = 1;
            break;
        }

        if(IsPrime(i)) *p_data->p_sum += i;
    }

    CloseHandle(p_data->h_)
}
// 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;
    }

if(count == 1) {
    CString str;
    str.Format(L"2~%u๊นŒ์ง€ ์†Œ์ˆ˜์˜ ํ•ฉ์€ %lld์ด๋‹ค. (%ums)", m_step, m_sum, GetTickCount() - m_start_tick);
    int index = m_data_list.InsertString(-1, str);
    m_data_list.SetCurSel(index);
}
}

๊ทธ๋Ÿฐ๋ฐ ๋ฌธ์ œ๋Š” ๋™์‹œ์— m_sum์„ ์“ฐ๊ฒŒ ๋˜๋Š”๊ฒฝ์šฐ???

// Dlg.cpp
CRITICAL_SETCTION gh_sum_lock;

// OnInitDlg
InitializeCriticalSection(&gh_sum_lock);

// OnDestroy
DeleteCriticalSection(&gh_sum_lock);
DWORD WINAPI InsertItemToList(void* ap_data)
{
    // ...

    if(IsPrime(i)) {
        EnterCriticalSection(&gh_sum_lock);
        *p_data->p_sum += i;
        LeaveCriticalSection(&gh_sum_lock);
    }

    // ...

CriticalSection์„ ์“ธ ๋•Œ ์ฃผ์˜ ์‚ฌํ•ญ์€ TerminateThread์™€ ๊ฐ™์€ ํ•จ์ˆ˜๋ฅผ ์“ฐ๋ฉด Enterํ›„ Leave๋ฅผ ํ•˜์ง€ ์•Š๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉฐ ๋ฐ๋“œ๋ฝ์— ๊ฑธ๋ฆด ์ˆ˜ ์žˆ๋‹ค.

์—ฌ๊ธฐ์„œ ์ค‘์š”ํ•œ ์ ์€ Critical Section์„ ๊ฑฐ๋Š” ์‹œ์ ์ด๋‹ค

๋งŒ์•ฝ ์•„๋ž˜์™€ ๊ฐ™์ด Critical Section์„ ๊ฑธ์—ˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ณด์ž

EnterCriticalSection(&gh_sum_lock);
if(IsPrime(i)) *p_data->p_sum += i;
LeaveCriticalSection(&gh_sum_lock);

๊ฐ€์žฅ ๋ถ€ํ•˜๊ฐ€ ํฐ ๊ตฌ๊ฐ„์ด IsPrime์„ ๊ตฌํ•˜๋Š” ๊ตฌ๊ฐ„์ธ๋ฐ ๊ฑฐ๊ธฐ์— CriticalSection์„???

์ •๋ง ์„ฑ๋Šฅ์ด ๋–จ์–ด์ง€๋Š” ์ฝ”๋“œ๊ฐ€ ๋  ๊ฒƒ์ด๋‹ค.

โš ๏ธ **GitHub.com Fallback** โš ๏ธ