1. 程式人生 > >VC++多執行緒程式設計-執行緒間的通訊和執行緒同步

VC++多執行緒程式設計-執行緒間的通訊和執行緒同步

執行緒間通訊

  一般而言,應用程式中的一個次要執行緒總是為主執行緒執行特定的任務,這樣,主執行緒和次要執行緒間必定有一個資訊傳遞的渠道,也就是主執行緒和次要執行緒間要進行通訊。這種執行緒間的通訊不但是難以避免的,而且在多執行緒程式設計中也是複雜和頻繁的,下面將進行說明。

  1. 使用全域性變數進行通訊

    由於屬於同一個程序的各個執行緒共享作業系統分配該程序的資源,故解決執行緒間通訊最簡單的一種方法是使用全域性變數。對於標準型別的全域性變數,我們建議使用volatile 修飾符,它告訴編譯器無需對該變數作任何的優化,即無需將它放到一個暫存器中,並且該值可被外部改變。如果執行緒間所需傳遞的資訊較複雜,我們可以定義一個結構,通過傳遞指向該結構的指標進行傳遞資訊。
     
  2. 使用自定義訊息

    我們可以在一個執行緒的執行函式中向另一個執行緒傳送自定義的訊息來達到通訊的目的。一個執行緒向另外一個執行緒傳送訊息是通過作業系統實現的。利用Windows作業系統的訊息驅動機制,當一個執行緒發出一條訊息時,作業系統首先接收到該訊息,然後把該訊息轉發給目標執行緒,接收訊息的執行緒必須已經建立了訊息迴圈。

例程7 MultiThread7

  該例程演示瞭如何使用自定義訊息進行執行緒間通訊。首先,主執行緒向CCalculateThread執行緒傳送訊息WM_CALCULATE,CCalculateThread執行緒收到訊息後進行計算,再向主執行緒傳送WM_DISPLAY訊息,主執行緒收到該訊息後顯示計算結果。

  1. 建立一個基於對話方塊的工程MultiThread7,在對話方塊IDD_MULTITHREAD7_DIALOG中加入三個單選按鈕IDC_RADIO1,IDC_RADIO2,IDC_RADIO3,標題分別為1+2+3+4+......+10,1+2+3+4+......+50,1+2+3+4+......+100。加入按鈕IDC_SUM,標題為“求和”。加入標籤框IDC_STATUS,屬性選中“邊框”;
  2. 在MultiThread7Dlg.h中定義如下變數:
    protected:
     int nAddend;
    代表加數的大小。

    分別雙擊三個單選按鈕,新增訊息響應函式:
    void CMultiThread7Dlg::OnRadio1() 
    {
     nAddend=10;
    }
    
    void CMultiThread7Dlg::OnRadio2() 
    {
     nAddend=50;
     
    }
    
    void CMultiThread7Dlg::OnRadio3() 
    {
     nAddend=100;
     
    }
    並在OnInitDialog函式中完成相應的初始化工作:
    BOOL CMultiThread7Dlg::OnInitDialog()
    {
    ……
     ((CButton*)GetDlgItem(IDC_RADIO1))->SetCheck(TRUE);
     nAddend=10;
    ……
    在MultiThread7Dlg.h中新增:
    #include "CalculateThread.h"
    #define WM_DISPLAY WM_USER+2
    class CMultiThread7Dlg : public CDialog
    {
    // Construction
    public:
     CMultiThread7Dlg(CWnd* pParent = NULL); // standard constructor
     CCalculateThread* m_pCalculateThread;
    ……
    protected:
     int nAddend;
     LRESULT OnDisplay(WPARAM wParam,LPARAM lParam);
    ……
    在MultiThread7Dlg.cpp中新增:
    BEGIN_MESSAGE_MAP(CMultiThread7Dlg, CDialog)
    ……
     ON_MESSAGE(WM_DISPLAY,OnDisplay)
    END_MESSAGE_MAP()
    
    LRESULT CMultiThread7Dlg::OnDisplay(WPARAM wParam,LPARAM lParam)
    {
     int nTemp=(int)wParam;
     SetDlgItemInt(IDC_STATUS,nTemp,FALSE);
    
      return 0;
    
    }
    以上程式碼使得主執行緒類CMultiThread7Dlg可以處理WM_DISPLAY訊息,即在IDC_STATUS標籤框中顯示計算結果。
  3. 雙擊按鈕IDC_SUM,新增訊息響應函式:
    void CMultiThread7Dlg::OnSum() 
    {
     m_pCalculateThread=
      (CCalculateThread*)AfxBeginThread(RUNTIME_CLASS(CCalculateThread));
    
     Sleep(500);
    
     m_pCalculateThread->PostThreadMessage(WM_CALCULATE,nAddend,NULL);
    }
    OnSum()函式的作用是建立CalculateThread執行緒,延時給該執行緒傳送WM_CALCULATE訊息。
  4. 右擊工程並選中“New Class…”為工程新增基類為 CWinThread 派生執行緒類 CCalculateThread。

    在檔案CalculateThread.h 中新增
    #define WM_CALCULATE WM_USER+1 
    class CCalculateThread : public CWinThread
    {
    ……
    protected:
     afx_msg LONG OnCalculate(UINT wParam,LONG lParam);
    ……
    在檔案CalculateThread.cpp中新增
    LONG CCalculateThread::OnCalculate(UINT wParam,LONG lParam)
    {
     int nTmpt=0;
     for(int i=0;i<=(int)wParam;i++)
     {
      nTmpt=nTmpt+i;
     }
    
     Sleep(500);
        ::PostMessage((HWND)(GetMainWnd()->GetSafeHwnd()),WM_DISPLAY,nTmpt,NULL);
    
     return 0;
    }
    BEGIN_MESSAGE_MAP(CCalculateThread, CWinThread)
     //{{AFX_MSG_MAP(CCalculateThread)
      // NOTE - the ClassWizard will add and remove mapping macros here.
     //}}AFX_MSG_MAP
     ON_THREAD_MESSAGE(WM_CALCULATE,OnCalculate)
    //和主執行緒對比,注意它們的區別
    END_MESSAGE_MAP()
    在CalculateThread.cpp檔案的開頭新增一條:
    #include "MultiThread7Dlg.h"
      以上程式碼為 CCalculateThread 類添加了 WM_CALCULATE 訊息,訊息的響應函式是 OnCalculate,其功能是根據引數 wParam 的值,進行累加,累加結果在臨時變數nTmpt中,延時0.5秒,向主執行緒傳送WM_DISPLAY訊息進行顯示,nTmpt作為引數傳遞。

編譯並執行該例程,體會如何線上程間傳遞訊息。

執行緒的同步

  雖然多執行緒能給我們帶來好處,但是也有不少問題需要解決。例如,對於像磁碟驅動器這樣獨佔性系統資源,由於執行緒可以執行程序的任何程式碼段,且執行緒的執行是由系統排程自動完成的,具有一定的不確定性,因此就有可能出現兩個執行緒同時對磁碟驅動器進行操作,從而出現操作錯誤;又例如,對於銀行系統的計算機來說,可能使用一個執行緒來更新其使用者資料庫,而用另外一個執行緒來讀取資料庫以響應儲戶的需要,極有可能讀資料庫的執行緒讀取的是未完全更新的資料庫,因為可能在讀的時候只有一部分資料被更新過。

  使隸屬於同一程序的各執行緒協調一致地工作稱為執行緒的同步。MFC提供了多種同步物件,下面我們只介紹最常用的四種:

  • 臨界區(CCriticalSection)
  • 事件(CEvent)
  • 互斥量(CMutex)
  • 訊號量(CSemaphore)
     

通過這些類,我們可以比較容易地做到執行緒同步。

A、使用 CCriticalSection 類

  當多個執行緒訪問一個獨佔性共享資源時,可以使用“臨界區”物件。任一時刻只有一個執行緒可以擁有臨界區物件,擁有臨界區的執行緒可以訪問被保護起來的資源或程式碼段,其他希望進入臨界區的執行緒將被掛起等待,直到擁有臨界區的執行緒放棄臨界區時為止,這樣就保證了不會在同一時刻出現多個執行緒訪問共享資源。

CCriticalSection類的用法非常簡單,步驟如下:
 

  1. 定義CCriticalSection類的一個全域性物件(以使各個執行緒均能訪問),如CCriticalSection critical_section;
  2. 在訪問需要保護的資源或程式碼之前,呼叫CCriticalSection類的成員Lock()獲得臨界區物件:
    critical_section.Lock();
    線上程中呼叫該函式來使執行緒獲得它所請求的臨界區。如果此時沒有其它執行緒佔有臨界區物件,則呼叫Lock()的執行緒獲得臨界區;否則,執行緒將被掛起,並放入到一個系統佇列中等待,直到當前擁有臨界區的執行緒釋放了臨界區時為止。
  3. 訪問臨界區完畢後,使用CCriticalSection的成員函式Unlock()來釋放臨界區:
    critical_section.Unlock();
    再通俗一點講,就是執行緒A執行到critical_section.Lock();語句時,如果其它執行緒(B)正在執行critical_section.Lock();語句後且critical_section. Unlock();語句前的語句時,執行緒A就會等待,直到執行緒B執行完critical_section. Unlock();語句,執行緒A才會繼續執行。

下面再通過一個例項進行演示說明。


例程8 MultiThread8

  1. 建立一個基於對話方塊的工程MultiThread8,在對話方塊IDD_MULTITHREAD8_DIALOG中加入兩個按鈕和兩個編輯框控制元件,兩個按鈕的ID分別為IDC_WRITEW和IDC_WRITED,標題分別為“寫‘W’”和“寫‘D’”;兩個編輯框的ID分別為IDC_W和IDC_D,屬性都選中Read-only;
  2. 在MultiThread8Dlg.h檔案中宣告兩個執行緒函式:
    UINT WriteW(LPVOID pParam);
    UINT WriteD(LPVOID pParam);
  3. 使用ClassWizard分別給IDC_W和IDC_D新增CEdit類變數m_ctrlW和m_ctrlD;
  4. 在MultiThread8Dlg.cpp檔案中新增如下內容:

    為了檔案中能夠正確使用同步類,在檔案開頭新增:
    #include "afxmt.h"
    定義臨界區和一個字元陣列,為了能夠在不同執行緒間使用,定義為全域性變數:
    CCriticalSection critical_section;
    char g_Array[10];
    新增執行緒函式:
    UINT WriteW(LPVOID pParam)
    {
     CEdit *pEdit=(CEdit*)pParam;
     pEdit->SetWindowText("");
     critical_section.Lock();
     //鎖定臨界區,其它執行緒遇到critical_section.Lock();語句時要等待
     //直至執行critical_section.Unlock();語句
     for(int i=0;i<10;i++)
     {
      g_Array[i]=''W'';
         pEdit->SetWindowText(g_Array);
      Sleep(1000);
     }
     critical_section.Unlock();
     return 0;
    
    }
    
    UINT WriteD(LPVOID pParam)
    {
     CEdit *pEdit=(CEdit*)pParam;
     pEdit->SetWindowText("");
     critical_section.Lock();
     //鎖定臨界區,其它執行緒遇到critical_section.Lock();語句時要等待
     //直至執行critical_section.Unlock();語句
     for(int i=0;i<10;i++)
     {
      g_Array[i]=''D'';
         pEdit->SetWindowText(g_Array);
      Sleep(1000);
     }
     critical_section.Unlock();
     return 0;
    
    }
  5. 分別雙擊按鈕IDC_WRITEW和IDC_WRITED,新增其響應函式:
    void CMultiThread8Dlg::OnWritew() 
    {
     CWinThread *pWriteW=AfxBeginThread(WriteW,
      &m_ctrlW,
      THREAD_PRIORITY_NORMAL,
      0,
      CREATE_SUSPENDED);
     pWriteW->ResumeThread();
    }
    
    void CMultiThread8Dlg::OnWrited() 
    {
     CWinThread *pWriteD=AfxBeginThread(WriteD,
      &m_ctrlD,
      THREAD_PRIORITY_NORMAL,
      0,
      CREATE_SUSPENDED);
     pWriteD->ResumeThread();
     
    }
    由於程式碼較簡單,不再詳述。編譯、執行該例程,您可以連續點選兩個按鈕,觀察體會臨界類的作用。

B、使用 CEvent 類

  CEvent 類提供了對事件的支援。事件是一個允許一個執行緒在某種情況發生時,喚醒另外一個執行緒的同步物件。例如在某些網路應用程式中,一個執行緒(記為A)負責監聽通訊埠,另外一個執行緒(記為B)負責更新使用者資料。通過使用CEvent 類,執行緒A可以通知執行緒B何時更新使用者資料。每一個CEvent 物件可以有兩種狀態:有訊號狀態和無訊號狀態。執行緒監視位於其中的CEvent 類物件的狀態,並在相應的時候採取相應的操作。
  在MFC中,CEvent 類物件有兩種型別:人工事件和自動事件。一個自動CEvent 物件在被至少一個執行緒釋放後會自動返回到無訊號狀態;而人工事件物件獲得訊號後,釋放可利用執行緒,但直到呼叫成員函式ReSetEvent()才將其設定為無訊號狀態。在建立CEvent 類的物件時,預設建立的是自動事件。 CEvent 類的各成員函式的原型和引數說明如下:

1、CEvent(BOOL bInitiallyOwn=FALSE,
          BOOL bManualReset=FALSE,
          LPCTSTR lpszName=NULL,
          LPSECURITY_ATTRIBUTES lpsaAttribute=NULL);
  • bInitiallyOwn:指定事件物件初始化狀態,TRUE為有訊號,FALSE為無訊號;
  • bManualReset:指定要建立的事件是屬於人工事件還是自動事件。TRUE為人工事件,FALSE為自動事件;
  • 後兩個引數一般設為NULL,在此不作過多說明。
2、BOOL CEvent::SetEvent();

   將 CEvent 類物件的狀態設定為有訊號狀態。如果事件是人工事件,則 CEvent 類物件保持為有訊號狀態,直到呼叫成員函式ResetEvent()將 其重新設為無訊號狀態時為止。如果CEvent 類物件為自動事件,則在SetEvent()將事件設定為有訊號狀態後,CEvent 類物件由系統自動重置為無訊號狀態。

如果該函式執行成功,則返回非零值,否則返回零。

3、BOOL CEvent::ResetEvent();

  該函式將事件的狀態設定為無訊號狀態,並保持該狀態直至SetEvent()被呼叫時為止。由於自動事件是由系統自動重置,故自動事件不需要呼叫該函式。如果該函式執行成功,返回非零值,否則返回零。我們一般通過呼叫WaitForSingleObject函式來監視事件狀態。前面我們已經介紹了該函式。由於語言描述的原因,CEvent 類的理解確實有些難度,但您只要通過仔細玩味下面例程,多看幾遍就可理解。

例程9 MultiThread9

  1. 建立一個基於對話方塊的工程MultiThread9,在對話方塊IDD_MULTITHREAD9_DIALOG中加入一個按鈕和兩個編輯框控制元件,按鈕的ID為IDC_WRITEW,標題為“寫‘W’”;兩個編輯框的ID分別為IDC_W和IDC_D,屬性都選中Read-only;
  2. 在MultiThread9Dlg.h檔案中宣告兩個執行緒函式:
    UINT WriteW(LPVOID pParam);
    UINT WriteD(LPVOID pParam);
  3. 使用ClassWizard分別給IDC_W和IDC_D新增CEdit類變數m_ctrlW和m_ctrlD;
  4. 在MultiThread9Dlg.cpp檔案中新增如下內容:

    為了檔案中能夠正確使用同步類,在檔案開頭新增

    #include "afxmt.h"
    定義事件物件和一個字元陣列,為了能夠在不同執行緒間使用,定義為全域性變數。
    CEvent eventWriteD;
    char g_Array[10];
    新增執行緒函式:
    UINT WriteW(LPVOID pParam)
    {
     CEdit *pEdit=(CEdit*)pParam;
     pEdit->SetWindowText("");
     for(int i=0;i<10;i++)
     {
      g_Array[i]=''W'';
         pEdit->SetWindowText(g_Array);
      Sleep(1000);
     }
     eventWriteD.SetEvent();
     return 0;
    
    }
    UINT WriteD(LPVOID pParam)
    {
     CEdit *pEdit=(CEdit*)pParam;
     pEdit->SetWindowText("");
     WaitForSingleObject(eventWriteD.m_hObject,INFINITE);
     for(int i=0;i<10;i++)
     {
      g_Array[i]=''D'';
         pEdit->SetWindowText(g_Array);
      Sleep(1000);
     }
     return 0;
    
    }
       仔細分析這兩個執行緒函式, 您就會正確理解CEvent 類。執行緒WriteD執行到 WaitForSingleObject(eventWriteD.m_hObject,INFINITE);處等待,直到事件eventWriteD為有訊號該執行緒才往下執行,因為eventWriteD物件是自動事件,則當WaitForSingleObject()返回時,系統自動把eventWriteD物件重置為無訊號狀態。
  5. 雙擊按鈕IDC_WRITEW,新增其響應函式:
    void CMultiThread9Dlg::OnWritew() 
    {
     CWinThread *pWriteW=AfxBeginThread(WriteW,
      &m_ctrlW,
      THREAD_PRIORITY_NORMAL,
      0,
      CREATE_SUSPENDED);
     pWriteW->ResumeThread();
    
     CWinThread *pWriteD=AfxBeginThread(WriteD,
      &m_ctrlD,
      THREAD_PRIORITY_NORMAL,
      0,
      CREATE_SUSPENDED);
     pWriteD->ResumeThread();
     
    }
    編譯並執行程式,單擊“寫‘W’”按鈕,體會事件物件的作用。

C、使用CMutex 類

  互斥物件與臨界區物件很像.互斥物件與臨界區物件的不同在於:互斥物件可以在程序間使用,而臨界區物件只能在同一程序的各執行緒間使用。當然,互斥物件也可以用於同一程序的各個執行緒間,但是在這種情況下,使用臨界區會更節省系統資源,更有效率。

D、使用CSemaphore 類

  當需要一個計數器來限制可以使用某個執行緒的數目時,可以使用“訊號量”物件。CSemaphore 類的物件儲存了對當前訪問某一指定資源的執行緒的計數值,該計數值是當前還可以使用該資源的執行緒的數目。如果這個計數達到了零,則所有對這個CSemaphore 類物件所控制的資源的訪問嘗試都被放入到一個佇列中等待,直到超時或計數值不為零時為止。一個執行緒被釋放已訪問了被保護的資源時,計數值減1;一個執行緒完成了對被控共享資源的訪問時,計數值增1。這個被CSemaphore 類物件所控制的資源可以同時接受訪問的最大執行緒數在該物件的構建函式中指定。

CSemaphore 類的建構函式原型及引數說明如下:

CSemaphore (LONG lInitialCount=1,
            LONG lMaxCount=1,
            LPCTSTR pstrName=NULL,
            LPSECURITY_ATTRIBUTES lpsaAttributes=NULL);
  • lInitialCount:訊號量物件的初始計數值,即可訪問執行緒數目的初始值;
  • lMaxCount:訊號量物件計數值的最大值,該引數決定了同一時刻可訪問由訊號量保護的資源的執行緒最大數目;
  • 後兩個引數在同一程序中使用一般為NULL,不作過多討論;

  在用CSemaphore 類的建構函式建立訊號量物件時要同時指出允許的最大資源計數和當前可用資源計數。一般是將當前可用資源計數設定為最大資源計數,每增加一個執行緒對共享資源的訪問,當前可用資源計數就會減1,只要當前可用資源計數是大於0的,就可以發出訊號量訊號。但是當前可用計數減小到0時,則說明當前佔用資源的執行緒數已經達到了所允許的最大數目,不能再允許其它執行緒的進入,此時的訊號量訊號將無法發出。執行緒在處理完共享資源後,應在離開的同時通過ReleaseSemaphore()函式將當前可用資源數加1。

下面給出一個簡單例項來說明 CSemaphore 類的用法。

例程10 MultiThread10

  1. 建立一個基於對話方塊的工程MultiThread10,在對話方塊IDD_MULTITHREAD10_DIALOG中加入一個按鈕和三個編輯框控制元件,按鈕的ID為IDC_START,標題為“同時寫‘A’、‘B’、‘C’”;三個編輯框的ID分別為IDC_A、IDC_B和IDC_C,屬性都選中Read-only;
  2. 在MultiThread10Dlg.h檔案中宣告兩個執行緒函式:
    UINT WriteA(LPVOID pParam);
    UINT WriteB(LPVOID pParam);
    UINT WriteC(LPVOID pParam);
  3. 使用ClassWizard分別給IDC_A、IDC_B和IDC_C新增CEdit類變數m_ctrlA、m_ctrlB和m_ctrlC;
  4. 在MultiThread10Dlg.cpp檔案中新增如下內容:

    為了檔案中能夠正確使用同步類,在檔案開頭新增:

    #include "afxmt.h"
    定義訊號量物件和一個字元陣列,為了能夠在不同執行緒間使用,定義為全域性變數:
    CSemaphore semaphoreWrite(2,2); //資源最多訪問執行緒2個,當前可訪問執行緒數2個 
    char g_Array[10];

    新增三個執行緒函式:

    UINT WriteA(LPVOID pParam)
    {
     CEdit *pEdit=(CEdit*)pParam;
     pEdit->SetWindowText("");
     WaitForSingleObject(semaphoreWrite.m_hObject,INFINITE);
     CString str;
     for(int i=0;i<10;i++)
     {
            pEdit->GetWindowText(str);
      g_Array[i]=''A'';
      str=str+g_Array[i];
         pEdit->SetWindowText(str);
      Sleep(1000);
     }
     ReleaseSemaphore(semaphoreWrite.m_hObject,1,NULL);
     return 0;
    
    }
    UINT WriteB(LPVOID pParam)
    {
     CEdit *pEdit=(CEdit*)pParam;
     pEdit->SetWindowText("");
     WaitForSingleObject(semaphoreWrite.m_hObject,INFINITE);
     CString str;
     for(int i=0;i<10;i++)
     {
    
            pEdit->GetWindowText(str);
      g_Array[i]=''B'';
      str=str+g_Array[i];
         pEdit->SetWindowText(str);
      Sleep(1000);
     }
     ReleaseSemaphore(semaphoreWrite.m_hObject,1,NULL);
     return 0;
    
    }
    UINT WriteC(LPVOID pParam)
    {
     CEdit *pEdit=(CEdit*)pParam;
     pEdit->SetWindowText("");
     WaitForSingleObject(semaphoreWrite.m_hObject,INFINITE);
     for(int i=0;i<10;i++)
     {
      g_Array[i]=''C'';
         pEdit->SetWindowText(g_Array);
      Sleep(1000);
     }
     ReleaseSemaphore(semaphoreWrite.m_hObject,1,NULL);
     return 0;
    
    }
    這三個執行緒函式不再多說。在訊號量物件有訊號的狀態下,執行緒執行到WaitForSingleObject語句處繼續執行,同時可用執行緒數減1;若執行緒執行到WaitForSingleObject語句時訊號量物件無訊號,執行緒就在這裡等待,直到訊號量物件有訊號執行緒才往下執行。
  5. 雙擊按鈕IDC_START,新增其響應函式:
    void CMultiThread10Dlg::OnStart() 
    {
     CWinThread *pWriteA=AfxBeginThread(WriteA,
      &m_ctrlA,
      THREAD_PRIORITY_NORMAL,
      0,
      CREATE_SUSPENDED);
     pWriteA->ResumeThread();
    
     CWinThread *pWriteB=AfxBeginThread(WriteB,
      &m_ctrlB,
      THREAD_PRIORITY_NORMAL,
      0,
      CREATE_SUSPENDED);
     pWriteB->ResumeThread();
    
     CWinThread *pWriteC=AfxBeginThread(WriteC,
      &m_ctrlC,
      THREAD_PRIORITY_NORMAL,
      0,
      CREATE_SUSPENDED);
     pWriteC->ResumeThread();
    
     
    }

好吧,多執行緒程式設計就介紹到這裡,希望本文能對您有所幫助。


相關推薦

程序通訊執行同步區別

執行緒間通訊:由於多執行緒共享地址空間和資料空間,所以多個執行緒間的通訊是一個執行緒的資料可以直接提供給其他執行緒使用,而不必通過作業系統(也就是核心的排程)。 程序的通訊機制主要有:管道、有名管道、訊息佇列、訊號量、共享空間、訊號、套接字。 linux中程序間通訊和執行緒間通訊的區別:

Android程序通訊執行通訊

程序間和執行緒間通訊 這個知識點算是高階知識點, 執行緒和程序 首先要區分執行緒和程序的區別: 執行緒是cup最小排程單元; 程序是一系列執行緒的集合。 其實區分程序和執行緒通訊有一個很好的方法:程式是否重新起了一個虛擬機器,因為不同程序會啟動不

VC++執行程式設計-執行通訊執行同步

執行緒間通訊   一般而言,應用程式中的一個次要執行緒總是為主執行緒執行特定的任務,這樣,主執行緒和次要執行緒間必定有一個資訊傳遞的渠道,也就是主執行緒和次要執行緒間要進行通訊。這種執行緒間的通訊不但是難以避免的,而且在多執行緒程式設計中也是複雜和頻繁的,下面將進行說明。

MFC筆記(四)——執行程式設計1:模組、程序、執行的基本概念

一、模組、程序、執行緒 1.1 模組         一段可執行的程式(包括EXE和DLL),其程式程式碼、資料、資源被載入到記憶體中,由系統建立一個數據結構來管理它。這段程式就是一個模組。這裡所說

Java執行程式設計-(5)-使用Lock物件實現同步以及執行通訊

前幾篇: 在《Java多執行緒程式設計-(4)-執行緒間通訊機制的介紹與使用》已經學習了,可以使用方法wait/notify 結合同步關鍵字syn

安卓執行通訊程序之間通訊有什麼不同?分別怎麼實現?

**當一個程式第一次啟動的時候,Android會去動一個Linux進行和一個主執行緒,預設情況下,所有改程式元件都將在該程序和執行緒中 執行,同時Android會為每個應用程式分配一個單獨的Linux使用者,Android會盡量保留一個正在執行的程序,只在記憶體資源出現不足時,Andro

C++11執行程式設計 第三章: 如何向執行傳參

C++11 Multithreading – Part 3: Carefully Pass Arguments to Threads Varun January 22, 2015 C++11 Multithreading – Part 3: Carefully Pass Ar

執行程式設計】 synchronized全域性鎖例項鎖的區別

例項鎖 -- 鎖在某一個例項物件上。如果該類是單例,那麼該鎖也具有全域性鎖的概念。                例項鎖對應的就是synchronized關鍵字。全域性鎖 -- 該鎖針對的是類,無論例項多少個物件,那麼執行緒都共享該鎖。                全域性鎖

Java執行程式設計-(12)-Java中的佇列同步器AQSReentrantLock鎖原理簡要分析

原文出自 : https://blog.csdn.net/xlgen157387/article/details/78341626 一、Lock介面 在上一篇文章中: Java多執行緒程式設計-(5)-使用Lock物件實現同步以及執行緒間通訊 介紹

C++——執行程式設計(二)std::mutex 執行同步、解決資源競爭問題

前言 執行緒同步 這裡的“同”不是同時、一起執行的意思,而是指協同、協助、互相配合。執行緒同步是指多個執行緒協同步調,按預定的先後次序進行執行。 執行緒A和B一塊配合,A執行到一定程度時要依靠B的某個結果,於是停下來,示意B執行;B依言執行,再將結果給A;

Java 執行程式設計設計模式之 Thread Pool(執行池)

Java 中建立一個執行緒往往意味著JVM 會建立相應依賴於宿主機作業系統的本地執行緒(Native Thread)。 Thread Pool 模式的本質是使用極其有限的資源去處理相對無限的任務。核心思想是使用佇列對待處理的任務進行快取,並複用一定數量的工作者

執行程式設計部落格推薦及phread執行的深入理解

###Date:2017/10/31 轉載自: http://blog.csdn.net/lovecodeless/article/details/24468107(該部落格中有詳細的多執行緒程式設

C++執行--執行通訊執行同步

原文地址:http://blog.csdn.net/yanpingsz/article/details/5891693(轉)                 http://blog.csdn.net/zjc0888/article/details/7372258 (轉)

c++11執行程式設計(一):建立執行的三種方法

c++11執行緒庫原始的c++標準僅支援單執行緒程式設計,新的c++標準(c++11或c++0x)於2011年釋出,引入了新的執行緒庫。 編譯器要求 Linux: gcc 4.8.1 (完全併發支援) Windows: Visual Studio 2012 and Min

Qt執行程式設計一:使用QSemaphorewaitCondition管理一系列資源

使用QSemaphore管理一系列資源。在Qt多執行緒程式設計中,可以使用QSemaphore來管理一系列相似資源。以下程式對Buffer的資源進行消耗與回收。定義了兩個QSemaphore freeElement表示空閒資源訊號量,usedElement表示佔用資源訊號

C#執行程式設計(一)程序與執行

一、 程序         簡單來說,程序是對資源的抽象,是資源的容器,在傳統作業系統中,程序是資源分配的基本單位,而且是執行的基本單位,程序支援併發執行,因為每個程序有獨立的資料,獨立的堆疊空間。一個程式想要併發執行,開多個程序即可。

c++11執行:std::future , std::promise執行的返回值

std::future物件可以和asych,std::packaged_task,std::promise一起使用。這篇文章集中討論std::future和std::promise。 我們經常會遇到需要得到執行緒返回結果的情況,現在的問題是我們如何實現。 舉個例子: 假設

java執行學習之一——執行的狀態、上下文切換執行監控

多執行緒 執行緒的狀態 1. NEW(圖中初始狀態):一個剛建立而未啟動的執行緒處於該狀態。由於一個執行緒例項只能被啟動一次,因此一個執行緒只可能有一次處於該狀態。 2. 可執行(RUNNABLE):表示處於改狀態的執行緒可以被JVM的執行緒排程器(scheduler)進

Java進階 ——— Java執行(一)之程序執行

引言 講到執行緒,不可避免的提到程序。而因為執行緒無法脫離程序單獨存在,那什麼是程序? 延伸閱讀,Java多執行緒系列文章 什麼是程序? 程序:具有一定獨立功能的程式關於某個資料集合上的一次執行活動,程序是系統進行資源分配和排程的最小單位。 例如手機執行的眾多

實戰Java高併發程式設計之Java記憶體模型執行安全

Java記憶體模型 原子性: 是指一個操作是不可中斷的.即使多個執行緒一起執行的時候,一個操作一旦開始,就不會被其他執行緒干擾. 一般CPU的指令是原子的. Q:i++是原子操作嗎? A:不是.