前些時間用了一次並行處理,發現還是挺好用的,效率提高了不少,今天另外一個任務,也採用了並行處理,代碼(vs2015 MFC工程)的寫法如下:
int m_tdcCount = 4;
int m_threadIndex;
void ATaskThread()
{
CString strText;
DWORD dwId;
int threadIndex;
{
autounlock();
threadIndex = m_threadIndex++;
dwId = GetCurrentThreadId();
strText.Format(TEXT("第%d個線程的ID號:%d = 0x%x.\n"), threadIndex, dwId, dwId);
OutputDebugString(strText);
}
Sleep(5000); // test only
... // 任務中的其它打印
... // my task process
{
autounlock();
m_tdcCount--;
}
}
void startMyTask()
{
CString strText;
m_tdcCount = 4;
m_threadIndex = 0;
strText.Format(TEXT("即將啓動的處理線程數:%d.\n"), m_tdcCount);
OutputDebugString(strText);
#pragma omp parallel num_threads(m_tdcCount)
ATaskThread();
// 等待結束,其實這裏應該不需要,因爲實際上是前面的任務結束後纔會到這裏來
OutputDebugString(TEXT("開始等待所有任務線程結束...\n"));
while (m_tdcCount > 0)
Sleep(100);
... // 收尾工作
}
入口爲 startMyTask(),其中採用並行建立了4個實際的任務處理線程ATaskThread()。過程中,採用全局變量m_tdcCount對任務的生命期進行控制:在建立線程之前設置爲4,即4個線程,一個任務線程一旦完成自己的任務,就對該變量減1,所以當該變量減到0時,就表明了全部任務的結束。但實際調試過程中和想像的有點出入,於是就在任務線程中添加了一個 Sleep(5000),使線程等待足夠長的時間,預期的打印:
即將啓動的處理線程數:4.
第0個線程的ID號:67376 = 0x10730.
第1個線程的ID號:69524 = 0x10f94.
第2個線程的ID號:68112 = 0x10a10.
第3個線程的ID號:67736 = 0x10898.
開始等待所有任務線程結束...
<任務中的其它打印>
或者是“開始等待所有任務線程結束...”可能往前提但位於第一行的後面,這樣都算正常,比如下面的也是正常的:
即將啓動的處理線程數:4.
第0個線程的ID號:67376 = 0x10730.
開始等待所有任務線程結束...
第1個線程的ID號:69524 = 0x10f94.
第2個線程的ID號:68112 = 0x10a10.
第3個線程的ID號:67736 = 0x10898.
<任務中的其它打印>
因爲任務線程中有個Sleep(5000),所以任務中的打印肯定應該排在"開始等待所有任務線程結束..."一行之後,但實際上打印卻是如下示的樣子:
即將啓動的處理線程數:4.
第0個線程的ID號:67376 = 0x10730.
第1個線程的ID號:69524 = 0x10f94.
第2個線程的ID號:68112 = 0x10a10.
第3個線程的ID號:67736 = 0x10898.
<任務中的其它打印>
開始等待所有任務線程結束...
即所有的任務都運行完了纔到調用ATaskThread()之後的地方。這樣看,用起來就方便了,不需要控制並行任務線程,把它當作一個普通的函數調用即可,不用害怕其後的語句和線程任務同時運行。