2015-11-19 44 views
0

我在c中創建一個web服務器。我想要它多進程,所以我需要在進程之間分享一些東西。在Windows中的奇怪錯誤共享內存

我已經使用共享內存,但有時我的進程崩潰的內存違規訪問。

共享內存的地址可能因進程而異。 Gdb調試似乎不可能(我也嘗試附加到正在運行的進程,仍然沒有太多成功)。

我已經從微軟網站下載了示例代碼,試圖運行它,發現在每次運行時指向內存地址的指針都不相同。

我有一個主進程,即每隔幾毫秒檢查一下存在兩個進程。每個過程都服務於一個客戶,然後死亡。

行爲是這樣的:有時,當我運行該程序時,它在首次嘗試使用共享內存時崩潰。有時需要許多重新生成的過程才能使程序崩潰。只需一個產卵過程,每次都能很好地工作。

其實這是程序只是一個Linux服務器的移植,所以我不認爲我在其他地方的指針做錯了。

這是在主過程創建存儲器映射的代碼:

SECURITY_ATTRIBUTES security = { 
    sizeof(security), NULL, TRUE 
}; 

hSharedMemory = CreateFileMapping(
      INVALID_HANDLE_VALUE, // use paging file 
      &security,    // Handle ereditabile 
      PAGE_READWRITE| SEC_NOCACHE | SEC_COMMIT,   // read/write access 
      0,      // maximum object size (high-order DWORD) 
      region_sz,    // maximum object size (low-order DWORD) 
      NULL);     // name of mapping object 
if (hSharedMemory == NULL) 
{ 
    printf("CreateFileMapping: %lu", GetLastError()); 
    exit(EXIT_FAILURE); 
} 

我會再與其他的東西手柄傳遞到與管道衍生的進程。

然後,它將打開使用memorymapping:

ptr = MapViewOfFile(hSharedMemory, // handle to map object 
        FILE_MAP_ALL_ACCESS, // read/write permission 
        0, 
        0, 
        region_sz); 

我讀過MSDN文檔,但無法找到任何想法,爲什麼發生這種情況。

在創建過程中,我已經將句柄inerithance參數設置爲TRUE。

我在Windows 8.1上使用mingw編譯器。

+0

訪問衝突可能是由您的代碼中的錯誤導致的(99%的機會)。所顯示的代碼是正確的,因此如果沒有完整的repro,我們將無法爲您提供幫助。 –

+0

我真的建議你讓gdb工作或嘗試valgrind(valgrind --leak-check = yes --trace-children = yes) –

+0

@SimonMourier認爲是這樣,但正如我所說,這只是一個可以運行的Linux程序的移植好。所以我試圖在兩個項目的差異中找到bug。 –

回答

1

您不能通過管道將句柄傳遞給其他進程。這不起作用。

MSDN

多個進程可共享同一文件的視圖通過使用單個共享文件映射對象或創建由相同的文件備份單獨的文件映射對象任一。 單個文件映射對象可以被多個進程共享,通過繼承進程創建時的句柄,複製句柄或打開文件映射對象的名稱。有關更多信息,請參閱 CreateProcess,DuplicateHandle和OpenFileMapping函數。

也是一個很好的信息來源:MSDN on Inheritance

我建議創建一個GUID並使用它作爲lpNameCreateFileMappingOpenFileMapping

+0

謝謝。請參閱我的編輯:在創建流程時,我已將句柄inerithance參數設置爲TRUE。這不夠嗎?或者我是否需要複製手柄? –

+0

另外,我已經試過這種方式。在Windows 7中,每當我想調試我的程序時,我都需要管理員權限才能運行該程序,並且無論如何都會崩潰。 –

+0

@FedericoPonzi這應該是足夠的,不需要重複HandHandle。 –