2012-01-27 36 views
0

我有3個程序,每個程序需要在一個文件中寫入1000次。互斥必須以「F1 < < 1」,第二,「F1 < < 2」 他們不同步,如何使它每10本著作後切換程序如何使用互斥鎖自動交換3個進程?

#include "stdafx.h" 
#include <Windows.h> 
#include <fstream> 
#include <iostream> 
using namespace std; 
HANDLE ghMutex; 


void write() 
{ 
    ghMutex = OpenMutex(SYNCHRONIZE, false, (LPTSTR)"WriteData"); 
    for (int i=0; i<100; i ++) { 
      WaitForSingleObject(ghMutex, INFINITE); 
      ofstream f1("c:\\write.txt", ios_base::app); 
      for (int j=0; j<10; j++) 
        f1 << 2;   
      ReleaseMutex(ghMutex); 
      f1.close(); 
      Sleep(100); 
    } 
} 

void main(){ 
write(); 
} 

第一個程序? 請幫我用2個程序開始。

+1

你忘了提及這是家庭作業及你的努力來解決它。 – 2012-01-27 13:42:19

+0

我不認爲這是作業;一位教授會知道(我希望!)一個互斥體不能像這樣工作。 – MSalters 2012-01-27 14:17:55

+0

@ MSalters:並不意味着學生理解這個概念以及他們的教授;-) – 2012-01-27 15:04:58

回答

0

是否ghMutex在任何過程中有效?在OpenMutex()WaitForSingleObject()之後GetLastError()返回的值是多少?

您需要在其中一個進程中創建互斥鎖,然後其他進程才能打開它。幸運的是,CreateMutex完全符合你的需求:它創建互斥體,如果它不存在,並打開它,如果它。

而且您可能需要在釋放互斥鎖之前(而非之後)關閉流,以便在其他進程開始寫入之前刷新緩存的數據。

+0

如何連接它們?他們一起寫作。我認爲他們不會互相看到 – 2012-01-27 15:14:53

+0

@ user1173543:只需通過調用「CreateMutex」來替換對「OpenMutex」的調用即可。並檢查返回值:-)。在釋放互斥之前,您還應該關閉流。 – 2012-01-27 15:20:47

+0

我重命名爲CreateMutex並在釋放之前關閉流。這沒有幫助。 – 2012-01-27 15:31:38

1

從您的描述中確切地說明您希望程序的行爲如何。你是否希望程序保證進程是交替進行的,如果是這樣,你是否需要循環類型排序(例如,進程1,然後進程2,然後進程3,然後再進程1)?

但是,很明顯,您當前的互斥鎖使用不正確。首先,至少有一個進程必須調用CreateMutex()才能真正創建互斥鎖(否則不會有互斥鎖打開)。由於爲CreateMutex()的文件說:

如果lpName現有命名互斥對象的名稱相匹配,此功能要求MUTEX_ALL_ACCESS訪問權限。

假設請求更多的訪問是不是對你的問題(事實上並非如此),那麼你可以擁有所有實例調用CreateMutex()確保他們都有着相同的互斥鎖,並取其先開始實際創建的。

這是一個簡單的例子,它以不可預知的順序交替進行(允許重複),但是在連續10次正確寫入文件而不被併發作者中斷。

#include <Windows.h> 
#include <conio.h> 
#include <iostream> 
#include <fstream> 

int main (int, char **) 
{ 
    // get a named mutex. open the same mutex as other 
    // concurrent instances. 
    const ::HANDLE mutex = ::CreateMutexW(0, FALSE, L"Fubar"); 
    if (mutex == INVALID_HANDLE_VALUE) 
    { 
     const ::DWORD error = ::GetLastError(); 
     std::cerr 
      << "Could not open mutex (" << error << ")." 
      << std::endl; 
     return (EXIT_FAILURE); 
    } 

    // open the input file. notice the flags, you need to make 
    // sure the 2nd process doesn't overwrite whatver the first 
    // wrote, etc. 
    std::ofstream file("foo.txt", std::ios::app); 
    if (!file.is_open()) 
    { 
     std::cerr 
      << "Could not open file." 
      << std::endl; 
     return (EXIT_FAILURE); 
    } 

    // wait for user to unblock after launch. this gives time 
    // to start concurrent processes before we write to the 
    // file. 
    ::getch(); 

    // not sure how your application goes, but lets just 
    // repeatedly write to the file until we're fed up. 
    for (int j=0; j < 100; ++j) 
    { 
     // lock the mutex around the code that writes to the 
     // file in a loop. 
     ::WaitForSingleObject(mutex, INFINITE); 
     for (int i=0; i < 10; ++i) { 
      file << "process " << ::GetCurrentProcessId() << std::endl; 
     } 
     ::ReleaseMutex(mutex); 

     // slow down so the application doesn't finish before we 
     // unblock concurrent instances. 
     ::Sleep(100); 
    } 

    // don't forget to clean up! 
    ::CloseHandle(mutex); 
} 

開始這一過程(2或更多),當所有被髮射,按每個控制檯窗口一個鍵即可將有過程的多個實例開始寫。輸出文件將包含每個進程的10個輸出的burts。

+0

@安德烈卡倫謝謝!真的行!請回答,互斥體可以做循環式的排序嗎? – 2012-01-27 15:59:10

+0

@André:+1,你彌補了我的懶惰:) – 2012-01-27 16:17:20

+0

@ user1173543:用單個互斥體無法實現這個目標。您**可以通過每個進程一個互斥體來實現循環次序,其中每個進程在其自己的互斥鎖上擁有一個鎖並在完成寫入時釋放它。如果繼任者(並且只有正確的繼任者)正在等待這個互斥體,那麼你可能會實現這樣的事情。但是,這是一個更復雜的設置,對於一個示例可能有點複雜。這是一個留給讀者的練習;-) – 2012-01-27 22:15:16