線程間的通信實例

線程間的通信主要針對主線程和次線程來說。而線程間的同步是針對兩個或多個次線程來說的。

一般而言,應用程序中的一個次要線程總是爲主線程執行特定的任務,這樣,主線程和次要線程間必定有一個信息傳遞的渠道,也就是主線程和次要線程間要進行通信。這樣線程間的通信不但是難以避免的,而且在多線程編程中也是複雜和頻繁的。一般可以使用全局變量進行通信和自定義消息進行通信。

1.使用全局變量進行通信

由於屬於同一個進程的各個線程共享操作系統分配該進程的資源,所以可以通過全局變量來解決線程間的通信。建議使用 volatile 修飾符,它告訴編譯器無需對該變量進行任何的優化,即無需將它放到一個寄存器中,並且該值可被外部改變。如果線程間所需傳遞的信息比較複雜,可以定義一個結構,通過傳遞指向該結構的指針進行傳遞消息。接着讓線程監視這個變量(標誌位),當這個變量符合一定的條件時,表示線程應該終止。

bool bExit = 1;                     //全局變量,用來監視線程是否結束,可以在需要結束
                                    //線程的地方將 bExit 置爲 0
UINT WorkThread(LPVOID param)       //全局線程函數
{
    int nPos = 0;
    while(nPos < 500 && bExit)      
        nPos++;
    return 0;
}

2.使用自定義消息進行通信

博主寫過的自定義消息:https://blog.csdn.net/qq_41291253/article/details/103321802

可以在一個線程的執行函數中向另一個線程發送自定義的消息來達到通信的目的。一個線程向另一個線程發送消息是通過操作系統來實現的。利用 Windows 操作系統的消息驅動機制,當一個線程發出一條消息時,操作系統首先接收到該消息,然後把該消息轉發給目標線程(接收消息的線程必須已經建立了消息循環)。

使用 Windows 消息來進行通信,首先需要定義一個自定義消息,然後,需要時在一個線程中調用全局函數::PostMessage()向另一個線程發送自定義消息。PostMessage()函數原型爲

BOOL PostMessage(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam);
其中,參數hwnd爲要接收消息窗口的句柄,參數 Msg 爲消息的 ID,參數wParam lParam爲消息相關的參數。

例:編寫一個創建工作者線程的單文檔應用程序,當執行“延時”菜單命令時啓動一個工作者線程,延時 3 秒後傳遞消息。

生成一個單文檔應用程序

  • 爲應用程序添加“延時”菜單項,其 ID 爲 ID_PRIME
  • 利用類嚮導添加消息處理函數,並添加如下代碼
void CLi10_2View::OnPrime()
{
	// TODO: 在此添加命令處理程序代碼
	HWND hWnd = GetSafeHwnd();   //獲取當前窗口指針句柄
	AfxBeginThread(Calculateprime, hWnd, THREAD_PRIORITY_BELOW_NORMAL, 0); //啓動線程
}

//工作者線程/*
CWinThread * AfxBeginThread(AFX_THREADPROC pfnThreadProc,
    LPVOID pParam, int nPriority = THREAD_PRIORITY_NORMAL,
    UINT nStackSize = 0, DWORD dwCreateFlags = 0,
    LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL);
其中,參數pfnThreadProc是一個指向線程函數的指針,參數pParam的類型與線程函數參數類型完全一致,
該參數爲啓動線程時傳遞給線程函數的入口參數。其他幾個參數用於設置線程的優先級、線程的堆棧大小、
創建時是否立即運行及線程的安全屬性,這四個參數通常使用默認值。*/
  • 在.h 文件的類外面聲明全局線程函數並添加自定義消息 ID
#define WM_CALCULATE  WM_USER + 100
UINT Calculateprime(LPVOID pPrame);
  • 在.h 文件的消息映射部分加入如下代碼 
afx_msg LONG OnThreadEnd(WPARAM wParam, LPARAM lParam);

 

  • 在.cpp 文件的消息映射下面加入如下代碼,並在文件起始位置定義一個全局變量 n 用於線程間的通信
ON_MESSAGE(WM_CALCULATE, OnThreadEnd)

  • 在.cpp 文件中定義線程函數
UINT Calculateprime(LPVOID pParam)
{
	Sleep(3000);
	n = 100;
	::PostMessage((HWND)pParam, WM_CALCULATE, n, 0);
	return 0;
}
  • 在.cpp 文件中添加消息處理函數 OnThreadEnd()。
LONG CLi10_2View::OnThreadEnd(WPARAM wParam, LPARAM lParam)
{
	CString str;
	str.Format("The Prime Numbers is %d.", n);
	MessageBox(str);
	return 0;
}
  • 編譯、鏈接並運行程序。選擇“延時”菜單命令,工作線程執行完畢後,自動顯示下圖結果
程序運行界面
點擊延時後 3S 結果

相應程序代碼下載: 鏈接:https://pan.baidu.com/s/1cmRETFCUuNMKKuyjR6EcMQ  密碼:d20a

https://download.csdn.net/download/qq_41291253/12013646 有 CSDN 會員的夥伴,還望支持下。

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