Linux使用共享記憶體通訊的程序同步退出問題

2021-08-20 09:01:36 字數 2018 閱讀 3482

**:

兩個甚至多個程序使用共享記憶體(shm)通訊,總遇到同步問題。這裡的「同步問題」不是說程序讀寫同步問題,這個用訊號量就好了。這裡的同步問題說的是同步退出問題,到底誰先退出,怎麼知道對方退出了。舉個例子:程序負責讀寫資料庫a,程序b負責處理資料。那麼程序a得比程序b晚退出才行,因為要儲存程序b處理完的資料。可是a不知道b什麼時候退出啊。a、b是無關聯的程序,也不知道對方的pid。它們唯一的關聯就是讀寫同一塊共享記憶體。正常情況下,程序b在共享記憶體中寫個標識:程序a你可以退出了,也是可以的。不過程序b可能是異常退出,連標識都來不及寫。其次,共享記憶體用來做資料通訊的,加這麼個標識感覺不太好,有濫用的感覺。

採用socket通訊沒有這個問題,因為程序b退出怎麼也會導致socket斷開,哪怕是超時。但shm卻沒有協議來檢測這些行為,如果自己也做乙個未免太麻煩。那就從共享記憶體下手吧。

共享記憶體是由核心來管理的,乙個程序刪除本身開啟的共享記憶體並不影響另乙個程序的共享記憶體,哪怕都是同一塊共享記憶體。這是因為共享記憶體在核心中乙個引用計數,乙個程序使用該共享記憶體就會導致引用計數加1。如果其中乙個程序呼叫了刪除函式,只有這個計數為0才會真正刪除共享記憶體。那麼,需要最後才退出的程序檢測這個計數就可以了。

在system v的共享記憶體中,建立乙個共享記憶體會初始化乙個結構:

struct shmid_ds ;

使用shmctl函式可以讀取該結構體,其中的shm_nattch就是使用該共享記憶體的程序數。

不過,現在有了新的posix標準,當然要用新標準了。shm_open建立的共享記憶體也具有「乙個程序刪除本身開啟的共享記憶體並不影響另乙個程序的共享記憶體」的特點。可是用shm_open建立的共享記憶體不再有上面的結構,那麼,核心是怎麼管理shm_open建立共享記憶體??看下面的原始碼:

/* shm_open - open a shared memory file */

#include

#include

#include

#include

#include

#include

intshm_open (const char *name, int oflag, mode_t mode)

/* on failure, just close file and give up */

if (flags == -1)

}return fd;

}我嚓,這就是建立乙個普通的檔案啊,只是建立的位置在/dev/shm下(也就是ram上)。再來看看刪除共享記憶體的函式shm_unlink:

/* shm_unlink - remove a shared memory file */

#include

#include

#include

#include

#include

intshm_unlink (const char *name)

這也只是乙個普通的unlink函式。也就是說,posix標準的共享記憶體就是乙個檔案。所謂的「乙個程序刪除本身開啟的共享記憶體並不影響另乙個程序的共享記憶體」就相當於你用fstream物件開啟了乙個檔案,然後去資料夾把檔案刪除了(也就是對檔案進行了unlink操作),可是fstream物件還可以正常讀寫檔案,並沒有什麼引用計數。這下好了,程序退出時又沒法同步了。

這個硬鏈結可以通過fstat函式獲取。可是要這樣實現的話,意味著需要先建立一塊共享記憶體,每個程序引用的時候需要呼叫link函式來建立乙個硬鏈結。問題解決了,可是這樣會在/dev/shm下多個n多個檔案。這可是ram啊,雖然現在的伺服器都比較牛,但這樣做也不太好吧。好吧,還有乙個flock檔案鎖。flock使用lock_sh引數多個程序對同乙個檔案加鎖。這樣,程序b初始化共享記憶體時加鎖(可以有多個這樣的程序),在退出(包括異常退出)時解鎖。程序a在退出時檢測這個鎖。當發現無鎖時說明可以安全退出了。

同步退出的問題基本解決了。來不及寫**去驗證,下次吧。

ps:核心unlink時應該也是有計數才知道當前有沒有程序開啟檔案,在什麼時候應該刪除檔案。這個還得去查資料,看用不用得上。另外lsof這個工具是可以檢測到所有開啟該共享記憶體的程序及相應的狀態。這個應該也是有對應的api的,只是現在還沒搞懂

linux通訊 共享記憶體

共享記憶體是效率最高的程序間通訊方式 程序可以直接讀寫記憶體,不需要任何資料的拷貝。多個程序共享一段記憶體,因此與需要依靠某種同步機制,如互斥鎖和訊號燈等。建立開啟共享記憶體 shmget share memory get 對映共享記憶體 shmat share memory attach 撤銷共享...

linux程序通訊 共享記憶體

共享記憶體是ipc機制中的第二個。他允許連個不相關的程序訪問同一塊邏輯記憶體,能夠有效地實現兩個程序間資料傳遞。int shmget key t key,sizr t size,int shm 建立共享記憶體 key為共享記憶體段的命名,size為以位元組為單位的記憶體容量,shm 包含9位元許可權...

Linux程序通訊 共享記憶體

對於linux來講,不同程序之間的記憶體是不能讀寫的,乙個程序只能讀寫自己所屬的記憶體。a程序是不能讀寫b程序記憶體的?如果程式確實想通過記憶體交換資料怎麼辦?linux提供共享記憶體機制。共享記憶體是由核心處於多個程序間交換資訊的目的而留出的一塊記憶體區 段 共享記憶體也需要設定相關許可權的。這段...