2014-01-23 107 views
39

this線程建議OP使用mmap()而不是shmget()來獲取Linux中的共享內存。 我訪問了this頁面和this頁面以獲取一些文檔,但第二個頁面給出了關於mmap()的一個模糊示例。Linux共享內存:shmget()vs mmap()?

作爲一個新手,需要在兩個進程之間共享一些信息(文本形式),我應該使用shmget()方法還是mmap()?爲什麼?

謝謝

鮑勃

回答

52

兩種方法都可行。 mmap方法有一點限制,然後shmget,但更容易使用。 shmget是舊的System V共享內存模型並具有最廣泛的支持。 mmap/shm_open是執行共享內存的新POSIX方法,更易於使用。如果你的操作系統允許使用POSIX共享內存,那麼我會建議使用它。

一些提示:

  • 如果你創建你的孩子通過fork然後mmapMAP_ANONYMOUS | MAP_SHARED是迄今爲止最簡單的方式 - 只需一個電話。
  • 如果您獨立啓動進程,但可以爲它們提供共享內存名稱,則shm_open(+ ftruncate)+ mmapMAP_SHARED是兩/三個調用。在某些操作系統上需要librt
  • 如果您的操作系統有/dev/shm/shm_open相當於在/dev/shm/中打開文件。
+0

謝謝你的所有有用的建議。現在我不會使用fork。 – BowPark

+1

但在mmap中修改內存時,硬盤上的文件會被自動修改?所以你經常對這個文件寫文章? – BowPark

+6

'/ dev/shm'是你的RAMdisk。如果使用文件支持的共享內存「mmap」,則該文件位於實際磁盤上,然後由操作系統來安排更新。通常,在停止使用映射或分頁守護程序決定將頁面交換出去之前,映射文件將不會更新。您可以通過調用'msync'來強制更新,這是在使用希望寫入磁盤的文件支持的映射時推薦的做法。 –

27

很多這些都與歷史和未來的方向有關。

曾幾何時,有兩個主要的(有點競爭的)UNIX版本 - 系統V和BSD。 SysV擁有自己的IPC版本,包括大型3共享內存,信號量和消息隊列。 POSIX走過來試圖團結一切。

所以目前我們有兩個版本 - posix共享內存,MQs,信號量和sysV版本。只是爲了讓事情變得更加混亂,sysV版本也是也是 posix的一部分。

所以基本上你的問題是你想使用Posix或sysV風格的共享內存?一般來說,大多數人都會採取長期觀點並選擇Posix,因爲這似乎是通向未來的道路。但是,實際上,sysV的東西如此嵌入到如此多的系統中,你必須懷疑它會永遠消失。

因此,消除長期的東西,它歸結爲什麼對您的項目和您的口味有意義。一般來說,sysV版本實際上更加強大一些,但它們有一個笨拙的界面,大多數人在第一次接觸時會覺得有些困惑。 sysV信號量和消息隊列尤其如此。就共享內存而言,可以認爲sysV和posix都很尷尬。 sysV版本攜帶笨重ftok和關鍵的東西,而posix結束了多次通話和一些競爭條件設置。從外部看,posix版本的優勢在於它們利用文件系統,並且可以使用標準命令行功能(如「rm」)進行維護,而不是依賴sysV要求的單獨實用程序(例如ipcs)。

那你應該使用哪一種?通常,posix版本。但是你應該真正熟悉sysV版本。它們的某些功能超出了您可能想要在特定情況下利用的posix版本的功能。

+2

你能解釋爲什麼你認爲System V版本更強大? –

+6

強大的可能是錯誤的詞。富勒功能也許?例如,sysv信號量範圍從正數到負數,可以增加或減少,可以撤消操作,如果進程死亡,可以報告最後一個進程對它們進行操作(如果擴展到報告線程,這會更有用),在內核中存在,因此您不必混淆共享內存,並且可以一次性創建整個系列。 sysv MQ具有msgtypes,它允許許多進程輕鬆共享相同的隊列並只處理特定的類型。 Posix MQ總是讀取最早的消息 – Duck