共享記憶體 與 mmap

2021-07-10 21:00:30 字數 4106 閱讀 1243

o————–共享記憶體

可以說是最有用的程序間通訊方式,也是最快的ipc形式。

兩個不同程序a、b共享記憶體的意思是,同一塊物理記憶體被對映到程序a、b各自的程序位址空間

程序a可以即時看到程序b對共享記憶體中資料的更新,反之亦然

由於多個程序共享同一塊記憶體區域,必然需要某種同步機制,互斥鎖和訊號量都可以

o————–採用共享記憶體通訊的乙個顯而易見的好處是效率高,因為程序可以直接讀寫記憶體,而不需要任何資料的拷貝

對比

①管道和訊息佇列等通訊方式,則需要在核心和使用者空間進行四次的資料拷貝

②共享記憶體則只拷貝兩次資料,

一次從輸入檔案到共享記憶體區

另一次從共享記憶體區到輸出檔案

o————–程序之間在共享記憶體時

並不總是讀寫少量資料後就解除對映,有新的通訊時,再重新建立共享記憶體區域

而是保持共享區域,直到通訊完畢為止,這樣,資料內容一直儲存在共享記憶體中,並沒有寫回檔案

往往是在解除對映時才寫回檔案的

多種共享記憶體方式:mmap()系統呼叫,posix共享記憶體,以及系統v共享記憶體
o————–核心怎樣保證各個程序定址到同乙個共享記憶體區域的記憶體頁面

①.乙個具體的檔案在開啟後,核心會在記憶體中為之建立乙個  struct inode  結構

③.乙個 address_space結構 與乙個偏移量能夠確定乙個 page cache 或 swap cache 中的乙個頁面

④.程序呼叫mmap()時,只是在程序空間內新增了一塊相應大小的緩衝區,設定相應的訪問標識

但並沒有建立程序空間到物理頁面的對映。因此,第一次訪問該空間時,會引發乙個缺頁異常

⑤.缺頁異常處理程式首先在swap cache中尋找目標頁(符合address_space以及偏移量的物理頁)

①如果找到,則直接返回位址

②如果沒有找到,則判斷該頁是否在交換區(swap area),如果在,則執行乙個換入操作

③如果上述兩種情況都不滿足,處理程式將分配新的物理頁面,並把它插入到page cache中。程序最終將更新程序頁表

⑥.所有程序在建立線性位址與實體地址之間的對映之後,不論程序各自的返回位址如何,實際訪問的必然是同乙個共享記憶體區域對應的物理頁

o————–mmap()及其相關系統呼叫

o------mmap() 系統呼叫 

使得程序之間通過對映同乙個普通檔案實現共享記憶體。

普通檔案被對映到程序位址空間後,程序可以向訪問普通記憶體一樣對檔案進行訪問

不必再呼叫read(),write()等操作

o------mmap() 系統呼叫形式

void* mmap ( void * addr , size_t len , int prot , int flags , int fd , off_t offset )

//返回值為最後檔案對映到程序空間的位址,程序可直接操作起始位址為該值的有效位址

引數:addr----指定檔案應被對映到程序空間的起始位址

len-----是對映到呼叫程序位址空間的位元組數,

prot----引數指定共享記憶體的訪問許可權

flags---由以下幾個常值指定

fd------為即將對映到程序空間的檔案描述字,一般由open()返回

//親緣關係的程序實現共享記憶體最好的方式應該是採用匿名記憶體對映的方式**}

offset--通常設為0,表示從檔案頭開始對映

o------系統呼叫munmap()

int munmap( void * addr, size_t len )

/*該呼叫在程序位址空間中解除乙個對映關係

當對映關係解除後,對原來對映位址的訪問將導致段錯誤發生

*/引數:

addr-----是呼叫mmap()時返回的位址

len------是對映區的大小

o-------系統呼叫msync()

int msync ( void * addr , size_t len, int flags)

/*一般說來,程序在對映空間的對共享內容的改變並不直接寫回到磁碟檔案中

往往在呼叫munmap()後才執行該操作

可以通過呼叫msync()實現磁碟上檔案內容與共享記憶體區的內容一致

*/

o————mmap()返回位址的訪問

/* 對於用mmap()對映普通檔案來說,程序會在自己的位址空間新增一塊空間,空間大小由mmap()的len引數指定

但是,程序並不一定能夠對全部新增空間都能進行有效訪問。

程序能夠訪問的有效位址大小取決於檔案被對映部分的大小

o————read & write 兩個程序間通訊**示例

```

/*-------------read.c-----------*/

#include #include #include #include #include #include #include typedef struct

people;

int main(int argc, char** argv) // map a normal file as shared mem:

munmap( p_map,sizeof(people)*10 );

exit(0);

}```

```/*-------------write.c-----------*/

#include #include #include #include #include #include #include #include typedef struct

people;

int main(int argc, char** argv) // map a normal file as shared mem:

printf(" initialize over \n ");

sleep(10);

munmap( p_map, sizeof(people)*10 );

printf( "umap ok \n" );

exit(0);

}```

o———–父子程序間通訊**示例

```

#include #include #include #include #include #include #include #include typedef struct

people;

int main(int argc, char** argv)

p_map->age = 100;

munmap(p_map,sizeof(people)*10); //實際上,程序終止時,會自動解除對映。

exit(10);

}for(i = 0;i<5;i++)

int status;

wait(&status);

sleep(5);

printf( "parent read: the first people,s age is %d\n",p_map->age );

printf("umap\n");

munmap( p_map,sizeof(people)*10 );

printf( "umap ok\n" );

if(wexitstatus(status))

printf("child become a zombie!\n");

exit(-1);

}```

o———–mmap()返回指標所能使用的頁面大小

```

#include #include #include #include #include #include #include typedef struct

people;

int main(int argc, char** argv)

munmap(p_map,sizeof(people)*10);

exit(0);

}```

mmap實現共享記憶體

mmap概念 mmap將乙個檔案或者其它物件對映進記憶體。檔案被對映到多個頁上,如果檔案的大小不是所有頁的大小之和,最後乙個頁不被使用的空間將會清零。mmap在使用者空間對映呼叫系統中作用很大。mmap操作提供了一種機制,讓使用者程式直接訪問裝置記憶體,這種機制,相比較在使用者空間和核心空間互相拷貝...

程序通訊 mmap記憶體共享

回頁首if fd 0 回頁首 include include include include typedef structpeople main int argc,char argv map a normal file as shared mem printf initialize over n s...

Linux 共享記憶體mmap函式

include void mmap void addr,size t length,int prot,int flags,int fd,off t offset 引數二 對映的大小 引數三 保護的方式有讀,寫,執行,空 prot read prot write prot exec prot none...