2017-11-10 36 views
0

我有2個進程。第一個將一些數據發送給另一個,同步每一步。 實際發送的數據如下:Mutex不同步C++

Process : A sends 1 
Process : B receives 1 
Process : A sends 2 
Process : B receives 2 

的問題是,當我運行它從一開始發送的所有數據的過程中A和我看到的是這樣的:

Process : A sends 1 
Process : A sends 2 
Process : A sends 3 
Process : B receives 3 

我一樣以下:

Process A 
    HANDLE mutex;  
    mutex = CreateMutex(NULL, FALSE, TEXT("mutex1")); 
    if (mutex == INVALID_HANDLE_VALUE) { 
     _tprintf(TEXT("Create mutex error !.\n"), GetLastError()); 
     return 1; 
    } 
    for (int i = 0; i < sender_length;i++) { 
     WaitForSingleObject(mutex,INFINITE); 
     sendToB(data); 
     ReleaseMutex(mutex); 
     } 

    CloseHandle(mutex); 

與B過程看起來像以下:

Process B: 

    HANDLE mutex; 

    mutex = OpenMutex(SYNCHRONIZE, FALSE, TEXT("mutex1")); 

    if (mutex == INVALID_HANDLE_VALUE) { 
     _tprintf(TEXT("Mutex error ! \n"), GetLastError()); 
     return 1; 
     } 
    for (int i = 0; i < sender_length;i++) { 
      WaitForSingleObject(mutex,INFINITE); 
      receiveFromA(data); 
      ReleaseMutex(mutex); 
      } 

     CloseHandle(mutex); 
+1

不要在您嘗試同步的代碼內部創建互斥鎖。 –

+5

你的互斥體的心智模型似乎是錯誤的。在這裏沒有任何問題可以回答,除了告訴你一個互斥體不會做你認爲它所做的事。 –

+5

一個互斥體只是說一次只能有一件事。它沒有說明各個參與者獲得它的順序。你所描述的是一個完全有效的結果。您可能需要一些排序。 – GManNickG

回答

1

我不確定這是否是您的問題,但我認爲它至少有貢獻者的可能性很大:Windows鎖一段時間以來一直不公平。有關詳細信息,請參閱Joe Duffy的文章Anti-convoy locks in Windows Server 2003 SP1 and Windows Vista

具體互斥達菲說以下(由我添加高亮):

當然,視窗鎖仍然是一個卻有點公平的。互斥鎖的等待列表按FIFO順序保存,操作系統始終將線程喚醒到等待隊列的前端。 ...現在,當鎖被取消時,仍然使用FIFO喚醒算法,但鎖立即被標記爲不可用。 另一個線程可以潛入並採取鎖之前的喚醒線程甚至計劃

,其他線程可以是剛剛發佈的鎖的線程。在你的代碼中,釋放互斥鎖的線程所做的下一件事就是重新獲取互斥鎖,這是一個很好的位置。

+2

即使使用公平的鎖,預期的結果也不能保證或甚至是特別可能的。人們需要在兩個方向上進行明確的同步才能獲得完美的乒乓球來回。一般來說,如果你正在寫一個類似管道的東西,但是你仍然需要超過一個互斥量來完成等待,那麼通常會提供一定程度的緩衝。 –

+0

使用連接到兩個進程的調試器可以通過強制執行「乒乓」序列來確認此假設 –

+0

在兩個WaitForSingleObject上設置斷點 –