2010年8月17日 星期二

Multi Thread 的小範例

經常會寫到 Multi Thread 的程式,卻常常要回頭翻以前寫的 Code 查語法,大概是不夠熟吧,所以這裡也筆記一下。

Windows SDK 啟動一個執行緒的方式是 ::CreateThread() 而 MFC 是用包裝好的 AfxBeginThread() 使用方法類似,所以僅記下較常使用的 MFC 範例。

假設某類別名稱為 T,並有一全域 g_T 物件,假設必須使用到的參數為 OBJ 類別


void T::GetFileMD5(OBJ &refData)
{
    OBJ *pobj = new OBJ;
    *pobj = refData;
    AfxBeginThread(GetFileMDThread, (LPVOID)pobj, THREAD_PRIORITY_NORMAL);
}

UINT GetFileMD5Thread(LPVOID pParam)
{
    OBJ* pobj = (OBJ*)pParam;
    g_T.GetFileMD5Core(*pobj);
    delete pobj;
    return 0;
}

void T::GetFileMD5Core(OBJ &refData)
{
    CString strFilePath = refData.m_strFilePath;
}


假設有一類別 T,沒有全域 g_T 物件


void T::GetFileMD5()
{
    AfxBeginThread(GetSongUrlThread, (LPVOID)this);
}

UINT GetFileMD5Thread(LPVOID pParam)
{
    T *pT = (T*)pParam;
    pT->GetFileMD5Core();
    return 0;
}

void T::GetFileMD5Core(OBJ &refData)
{
    CString strFIlePath = m_FilePath;
}


假設有一類別 T,且必須使用鎖定機制控制某緒的執行


CCriticalSection g_csFileMD5;

void T::GetFileMD5(OBJ *refData)
{
    m_bOfflineSongCancel = TRUE;
    // 有新的續程進來,將取消設為 True
    // m_bOfflineSongCancel 這種變數最好在宣告前加上 volatile 關鍵字,
    // 例如:volatile BOOL m_bOfflineSongCancel
    // 這可以確保此變數在改變時第一時間被寫入實體記憶體內,
    // 使其成為行程間可共用的物件
    OBJ *pobj = new OBJ;
    pobj = refData;
    // 每個 Thread 要有獨自的物件實體可以用,所以用 new 產生
    // Thread 裡面處理完了記得 delete 掉自己那份實體

    AfxBeginThread(GetFileMDThread, (LPVOID)pobj, THREAD_PRIORITY_NORMAL);
}

UINT GetFileMD5Thread(LPVOID pParam)
{
    CSingleLock slock(&g_csFileMD5);
    slock.Lock();
    OBJ* pobj = (OBJ*)pParam;
    g_T.GetFileMD5Core(*pobj);
    delete pobj;
    slock.Unlock();
    return 0;
}

void T::GetFileMD5Core(OBJ &refData)
{
    m_bOfflineSongCancel = FALSE;
    // 開始做緒程的重點事項,取消設為 False
    // 並在其中較需時間的流程中監控是否要取消
    CString strFilePath = refData.m_strFilePath;
    do
    {
        // m_bOfflineSongCancel 可以用來控制當有新的 Thread 被啟動時,
        // 可在第一時間中斷並結束先前沒必要的動作。
    }while(!m_bOfflineSongCancel);
}

沒有留言:

張貼留言