#副標= Visual Studio 2010開發平台(7) #大標=利用Asynchronous開發平行運算功能 #關鍵字:Asynchronous、VS2010、Parallel #作者=文/王寧疆 ==========box 範例1========== CImage m_imgSource; //管理應用程式所開啟的圖形檔案的內容的變數 CImage m_imgResult; //管理經過模糊處理的圖形內容的變數 BOOL m_bShowOrig; //判斷是否要顯示圖形檔案原有內容的變數 ============end============= ==========box 範例2========== BOOL C專案名稱Doc::OnOpenDocument(LPCTSTR lpszPathName) { if (!CDocument::OnOpenDocument(lpszPathName)) return FALSE; if (!m_imgSource.IsNull()) //如果使用者已經開啟過圖形檔案 m_imgSource.Detach(); //解除m_imgSource所管理的圖形檔案的內容 if (FAILED(m_imgSource.Load(lpszPathName)))  //從使用者選定的檔案名稱載入圖形內容 { AfxMessageBox(_T("圖形載入失敗!"),     MB_ICONWARNING);     //顯示圖形載入失敗的錯誤訊息 } return TRUE; } ============end=============    ==========box 範例3========== void C專案名稱View::OnDraw(CDC* pDC) { CImageProcessingDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (!pDoc) return; CRect rc; //宣告存放View顯示空間大小的變數 GetClientRect(&rc); //取得View顯示空間大小並存放在名稱為rc的變數 pDC->SetStretchBltMode(COLORONCOLOR); //設定顯示資料的方式為不保留螢幕現有的內容 if (pDoc->m_bShowOrig) //判斷是否要顯示原圖  { if (!pDoc->m_imgSource.IsNull()) //判斷m_imgSource變數是否準備妥圖形內容 pDoc->m_imgSource.StretchBlt (pDC->GetSafeHdc(), 0, 0, rc.Width(), rc.Height(), 0, 0, pDoc->m_imgSource.GetWidth(), pDoc->m_imgSource.GetHeight(), SRCCOPY); //將m_imgSource管理的內容顯示到應用程式的View管理的顯示空間 } else { if (!pDoc->m_imgResult.IsNull()) //判斷m_imgResult變數是否準備妥圖形內容 pDoc->m_imgResult.StretchBlt(pDC-> GetSafeHdc(), 0, 0, rc.Width(), rc.Height(), 0, 0, pDoc->m_imgResult.GetWidth(), pDoc->m_imgResult.GetHeight(), SRCCOPY); //將m_imgResult管理的內容顯示到應用程式的View管理的顯示空間 } } ============end============= ==========box 範例4========== void C專案名稱Doc::OnParallel() { if (!m_imgResult.IsNull()) //如果m_imgResult變數已經存有模糊處理過的圖形內容 m_imgResult.Destroy(); //清除m_imgResult變數管理的內容 m_imgResult.Create(m_imgSource.GetWidth(), m_imgSource.GetHeight(), m_imgSource.GetBPP()); //依據m_imgSource管理的圖形大小建立m_imgResult的大小 m_imgSource.BitBlt(m_imgResult.GetDC(), 0, 0, m_imgSource.GetWidth(), m_imgSource.GetHeight(), 0, 0, SRCCOPY); //將m_imgSource管理的圖形內容複製給m_imgResult m_imgResult.ReleaseDC(); //釋放m_imgResult使用的DC結構 DWORD dwStart = GetTickCount(); //開始計算處理時間 ParallelImageBlur(); //呼叫ParallelImageBlur方法對圖形內容進行模糊處理 DWORD dwEnd = GetTickCount(); //結束計算處理時間 m_bShowOrig = FALSE; //設定不顯示原始圖形內容 UpdateAllViews(NULL); //更新View目前顯示的內容 CString str; //宣告CString類別的變數 str.Format(_T("平行處理:\n%i 毫秒, \n%i 秒"), (dwEnd-dwStart), (dwEnd-dwStart)/1000); //將圖形模糊處理花費的時間轉成適合顯示的字串 AfxMessageBox(str, MB_ICONINFORMATION); //顯示圖形模糊處理所花費的時間 } ============end============= ==========box 範例5========== afx_msg void OnParallel(); ============end============= ==========box 範例6========== void C專案名稱Doc::ParallelImageBlur() { BYTE* pPixelsSrc = reinterpret_cast( m_imgSource.GetBits()); //取得存放圖形原始內容的記憶體 BYTE* pPixelsDst = reinterpret_cast( m_imgResult.GetBits());  //取得存放模糊處理後的圖形內容的記憶體 int iWidth = m_imgSource.GetWidth(); //取得原始圖形的寬度 int iHeight = m_imgSource.GetHeight(); //取得原始圖形的高度 int iPitch = m_imgSource.GetPitch(); //取得圖形內容存放格式 int iBlurSize = 10; //設定模糊區塊大小 parallel_for(iBlurSize, iHeight-iBlurSize, 1, [&](int y) //利用平行運算技術對圖形內容進行模糊處理 { for (int x=iBlurSize; x inputBuffer; //定義存放Agent之間溝通資料的儲存空間 protected: virtual void run() //定義平行運算的工作內容 { for (;;) //定義無窮迴圈 { string s = receive(&inputBuffer);    //從inputBuffer共用儲存空間讀取字串資料 if (s == "end")    //如果讀到的字串為"end",則結束平行運算工作 { done(); //宣告平行運算工作結束 return; //結束run方法 } cout << "Received message : "      << s << endl;       //輸出從inputBuffer共用儲存空間讀取到的字串資料 } } }; ============end============= ==========box 範例8========== #include #include #include #include "MyAgent.h" using namespace std; using namespace Concurrency; void main() { MyAgent Agent; //建立MyAgent類別的物件 Agent.start(); //啟動MyAgent負責執行的平行運算工作 for (;;) //定義無窮迴圈 { string s; //宣告存放字串的string類別的物件 cin >> s; //從鍵盤讀入一個字串 send(Agent.inputBuffer, s); //將讀到的字串存入放置字串的共用儲存空間 if (s == "end") //判斷讀到的字串內容是否為"end" break; //結束迴圈的執行 } agent::wait(&Agent); //等待Agent工作結束 } ============end=============