並行處理是一條語句

前些時間用了一次並行處理,發現還是挺好用的,效率提高了不少,今天另外一個任務,也採用了並行處理,代碼(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()之後的地方。這樣看,用起來就方便了,不需要控制並行任務線程,把它當作一個普通的函數調用即可,不用害怕其後的語句和線程任務同時運行。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章