簡體   English   中英

退出前關閉線程應用程序

[英]Close Thread Before Exit application

我想在退出主程序之前停止線程。 此代碼正確嗎? (簡化示例)

HANDLE hThread;
BOOL live = TRUE;



DWORD WINAPI Thread ( LPVOID lpParam )
{
..
while(live);
..
}



case WM_DESTROY:
{
live=FALSE;     
WaitForSingleObject(hThread, INFINITE);
}

同步線程的最安全方法是使用某些內核對象。 您可以使用CreateEvent創建“終止”事件,然后在線程回調函數中等待它:

#include <Windows.h>
#include <iostream>
using std::cout;
using std::cerr;
using std::endl;

DWORD WINAPI Callback(LPVOID lpVoid)
{
    HANDLE hTerminateEvent = *(reinterpret_cast<HANDLE*>(lpVoid));

    bool terminate = false;

    while(!terminate)
    {
        DWORD retVal = WaitForSingleObject(hTerminateEvent, 0);

        switch(retVal)
        {
            case WAIT_OBJECT_0: 
                cout << "Terminate Event signalled" << endl;
                terminate = true;
                break;
            case WAIT_TIMEOUT:
                cout << "Keep running..." << endl;
                Sleep(1000);
                break;
            case WAIT_FAILED:
                cerr << "WaitForSingleObject() failed" << endl;
                terminate = true;
                break;
        }
    }

    return 0;
}

int main()
{
    DWORD threadID = 0;
    HANDLE hTerminateEvent = CreateEvent(0, FALSE, FALSE, 0);
    HANDLE hThread = CreateThread(0, 0, Callback, &hTerminateEvent, 0, &threadID);  

    // allow some time to thread to live
    Sleep(20000);

    // set terminate event
    if(!SetEvent(hTerminateEvent))
    {
        cerr << "SetEvent() failed" << endl;        
        return 1;
    }

    // wait for thread to terminate
    DWORD retVal = WaitForSingleObject(hThread, INFINITE);

    switch(retVal)
    {
        case WAIT_OBJECT_0: 
            cout << "Thread terminated" << endl;            
            break;
        case WAIT_FAILED:
            cerr << "WaitForSingleObject() failed" << endl;         
            break;
    }

    CloseHandle(hThread);
    CloseHandle(hTerminateEvent);

    return 0;
}

輸出:

Keep running...
Keep running...
Keep running...
Keep running...
Keep running...
Keep running...
Keep running...
Keep running...
Keep running...
Keep running...
Keep running...
Keep running...
Keep running...
Keep running...
Keep running...
Keep running...
Keep running...
Keep running...
Keep running...
Keep running...
Terminate Event signalled
Thread terminated

為了確保線程看到live變化,您需要使live volatile

volatile BOOL live = TRUE;

不,這是不正確的。 您沒有任何東西可以保證線程能夠看到更改。 編譯器可以自由進行優化:

DWORD WINAPI Thread ( LPVOID lpParam )
{
..
while(live);
..
}

至:

DWORD WINAPI Thread ( LPVOID lpParam )
{
..
register bool temp=live;
while(temp);
..
}

那顯然是行不通的。

經驗法則是- 永遠不要在一個線程中訪問變量,而另一個線程可能正在修改它,除非您使用某種特定的機制來確保操作安全。 如果遵循該規則,您將不會遇到麻煩。

void onexxit() {
   /* do-it */
}

atexit( onexxit )函數呢

http://msdn.microsoft.com/pl-pl/library/tze57ck3.aspx

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM