プログラミングメモ →目次

スレッド(VC++)

スレッドを作成、起動、終了する処理のメモです。

1.スレッドを作成します。CreateThread()関数で、スレッドを作成します。

WINBASEAPI HANDLE WINAPI CreateThread(
    LPSECURITY_ATTRIBUTES lpThreadAttributes,
    DWORD dwStackSize,
    LPTHREAD_START_ROUTINE lpStartAddress,
    LPVOID lpParameter,
    DWORD dwCreationFlags,
    LPDWORD lpThreadId );

新しいスレッドの開始アドレスを指定しますが、それは、通常、WINAPI 呼び出し規約で定義された関数のアドレスを指定します。この関数の書式を次に示します。

DWORD WINAPI ThreadFunc(LPVOID)

2.スレッドを起動します。CreateThread()関数のdwCreationFlagsCREATE_SUSPENDEDに設定しなければ、CreateThread()関数が終わると、スレッド関数ThreadFunc()がすぐ走ります。CREATE_SUSPENDEDに設定すれば、後に、ResumeThread()関数でスレッド関数ThreadFunc()を起動できます。

3.スレッドを終了します。ThreadFunc()関数が終了したら、スレッドが自動的に終了します。WINBASEAPI VOID WINAPI ExitThread(DWORD dwExitCode)関数で、終了コードを指定できます。後で、WINBASEAPI BOOL WINAPI GetExitCodeThread(HANDLE hThread, LPDWORD lpExitCode)関数で、終了コードを調べられます。

4.スレッドを強制終了します。スレッド関数ThreadFunc()から走ったままで、WINBASEAPI BOOL WINAPI TerminateThread( HANDLE hThread, DWORD dwExitCode )関数で、スレッドを強制終了できます。

5.スレッドが終了したかをチェックします。WINBASEAPI DWORD WINAPI WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds)関数で、スレッドが終了したかどうかをチェックできます。

6.サンプル。

HANDLE hThread = NULL;
DWORD ThreadId;
int g_iCount = 0;
bool g_bRunning = false;
DWORD WINAPI MyThreadFunc(LPVOID lpParam)
{
    while (g_bRunning && g_iCount < 10)
    {
        TRACE("Count = %d\r\n", g_iCount);
        g_iCount ++;
        Sleep(1000);
    }
    ExitThread(0);
    return 0;
}

void CreateAndStartThread()
{
    g_iCount = 0;
    g_bRunning = true;
    hThread = CreateThread(NULL, 0, MyThreadFunc, NULL, 0, &ThreadId);
}

void CThreadTestDlg::OnButtonStart() 
{
    CreateAndStartThread();
}

void CThreadTestDlg::OnButtonStop() 
{
    g_bRunning = false;
    if (hThread)
    {
        if (WAIT_TIMEOUT == WaitForSingleObject(hThread, 5000))
        {
            TerminateThread(hThread, 0);
        }
        CloseHandle(hThread);
        hThread = NULL;
    }
}