linux程式間通訊-----System V共享記憶體總結例項
共享記憶體簡介
共享記憶體區是最快的IPC形式。一旦這樣的記憶體對映到共享它的程式的地址空間,這些程式間資料傳遞不再涉及到核心,換句話說是程式不再通過執行進入核心的系統呼叫來傳遞彼此的資料。
程式1對映到該共享記憶體區域後,就可以通過對映之後得到的首地址p1,直接對那一片共享記憶體區域進行操作;
程式2對映到同一塊記憶體區域後,也可以得到對映之後的那一片共享記憶體的首地址p2,通過p2可以直接對那一片共享記憶體區域進行操作;
System V共享記憶體API
1:建立共享記憶體
#include <sys/ipc.h>
#include <sys/shm.h>
int shmget(key_t key, size_t size, int shmflg);
key:這個共享記憶體段名字,可以自己指定,也可以通過ftok函式來生成一個隨機的keysize:共享記憶體大小
shmflg:由九個許可權標誌構成,它們的用法和建立檔案時使用的mode模式標誌是一樣的
返回值:成功返回一個非負整數,即該共享記憶體段的標識碼;失敗返回-1
ret = shmget(0x2234, sizeof(Teacher), 0666 | IPC_CREAT);//存在就使用舊的 不存在就建立
#include <sys/types.h>
#include <sys/ipc.h>
key_t ftok(const char *pathname, int proj_id);//隨機產生key值
#include <sys/types.h>
#include <sys/shm.h>
void *shmat(int shmid, const void *shmaddr, int shmflg);
shmid: 共享記憶體標識,就是函式shmget的返回值shmflg:它的兩個可能取值是SHM_RND和SHM_RDONLY
返回值:成功返回一個指標,指向共享記憶體第一個節;失敗返回-1
shmaddr:指定連線的地址
shmaddr為NULL,核心自動選擇一個地址
shmaddr不為NULL且shmflg無SHM_RND標記,則以shmaddr為連線地址。
shmaddr不為NULL且shmflg設定了SHM_RND標記,則連線的地址會自動向下調整為SHMLBA的整數倍。公式:shmaddr - (shmaddr % SHMLBA)
shmflg=SHM_RDONLY,表示連線操作用來只讀共享記憶體
3:將共享記憶體段與當前程式脫離
#include <sys/types.h>
#include <sys/shm.h>
int shmdt(const void *shmaddr);
shmaddr: 由shmat所返回的指標返回值:成功返回0;失敗返回-1
注意:將共享記憶體段與當前程式脫離不等於刪除共享記憶體段
4:用於控制共享記憶體
#include <sys/ipc.h>
#include <sys/shm.h>
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
shmid:由shmget返回的共享記憶體標識碼
cmd:將要採取的動作(有三個可取值)
buf:指向一個儲存著共享記憶體的模式狀態和訪問許可權的資料結構
返回值:成功返回0;失敗返回-1
IPC_STAT:獲得共享記憶體資料結構的資訊
IPC_SET :設定共享記憶體資料結構的資訊
IPC_RMID:刪除共享記憶體段
struct shmid_ds {
struct ipc_perm shm_perm; /* Ownership and permissions */
size_t shm_segsz; /* Size of segment (bytes) */
time_t shm_atime; /* Last attach time */
time_t shm_dtime; /* Last detach time */
time_t shm_ctime; /* Last change time */
pid_t shm_cpid; /* PID of creator */
pid_t shm_lpid; /* PID of last shmat(2)/shmdt(2) */
shmatt_t shm_nattch; /* No. of current attaches */
...
};
The ipc_perm structure is defined as follows (the highlighted fields are settable using IPC_SET):
struct ipc_perm {
key_t __key; /* Key supplied to shmget(2) */
uid_t uid; /* Effective UID of owner */
gid_t gid; /* Effective GID of owner */
uid_t cuid; /* Effective UID of creator */
gid_t cgid; /* Effective GID of creator */
unsigned short mode; /* Permissions + SHM_DEST and
SHM_LOCKED flags */
unsigned short __seq; /* Sequence number */
};
例項1:
程式1建立鍵值是0x1111的共享記憶體,大小為1024位元組;程式1從標準輸入讀入資料並寫入到共享記憶體中;當程式1輸入over的時候,刪除該共享記憶體,並退出;程式2開啟鍵值是0x1111的共享記憶體,並從裡面讀取資料然後輸出到標準輸出上面;當程式2收到over之後退出;
備註:當兩個程式都執行的時候,輸入命令ipcs可以看到鍵值是0x1111的共享記憶體的連線數是2,也就是說有兩個程式已經連線到了該共享記憶體區域;
write_shm.cpp
/*************************************************************************
> File Name: write_shm.cpp
> Author:
> Mail:
> Created Time: 2015年12月21日 星期一 11時15分23秒
************************************************************************/
#include <iostream>
#include <cstdlib>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
using namespace std;
/*
1: 建立一塊共享記憶體
2:連線到共享記憶體,並向共享記憶體中寫入資料
3:脫離該共享記憶體區域
*/
#define SHMSIZE 1024
int main(int argc, char *argv[])
{
/*
if(argc < 2){
cout << "input the pathname fo generate key..."<< endl;
exit(-1);
}*/
key_t key = 0x1111;//ftok(argv[1], 'a');
int shmid = shmget(key, SHMSIZE, 0666|IPC_CREAT);
if(shmid == -1){
cerr << "shmget error ...." << endl;
exit(-1);
}
char * p = (char *)shmat(shmid, NULL, 0);
pid_t pid = getpid();
cout << "process " << pid << " write: ";
while(cin.getline(p, SHMSIZE)){
if(strcmp(p, "over") == 0){
break;
}
cout << "process " << pid << " write: ";
}
//脫離該共享記憶體區域,並刪除該共享記憶體區域
shmdt(p);
shmctl(shmid, IPC_RMID, NULL);
cout << "已經刪除了共享記憶體,並退出。\n";
exit(0);
}
read_shm.cpp
/*************************************************************************
> File Name: read_shm.cpp
> Author:
> Mail:
> Created Time: 2015年12月21日 星期一 11時15分23秒
************************************************************************/
#include <iostream>
#include <cstdlib>
#include <sys/ipc.h>
#include <string.h>
#include <sys/shm.h>
#include <unistd.h>
#include <sys/types.h>
using namespace std;
/*
連線到共享記憶體,並向共享記憶體中讀入資料
脫離該共享記憶體區域
*/
#define SHMSIZE 1024
int main(int argc, char *argv[])
{
key_t key = 0x1111;
//當共享記憶體中有資料的時候它才會立刻返回,否則該函式會阻塞在這裡
int shmid = shmget(key, SHMSIZE, 0666);
if(shmid == -1){
cerr << "shmget error ...." << endl;
exit(-1);
}
pid_t pid = getpid();
char * p = (char *)shmat(shmid, NULL, 0);
cout << "process " << pid << " read: ";
while(1){
if(strlen(p) != 0)
cout << p << endl;
else
continue;
if(strcmp(p, "over") == 0){
break;
}
cout << "process " << pid << " read: ";
memset(p, 0, SHMSIZE);
}
cout << "程式退出。\n";
exit(0);
}
相關文章
- Linux 程式間通訊之System V 共享記憶體Linux記憶體
- linux程式間通訊-----System V訊息佇列總結例項Linux佇列
- system-v IPC共享記憶體通訊記憶體
- Android native程式間通訊例項-binder結合共享記憶體Android記憶體
- Linux系統程式設計之程式間通訊方式:共享記憶體例項演示Linux程式設計記憶體
- Linux程式間通訊之共享記憶體Linux記憶體
- Linux程式間通訊——使用共享記憶體Linux記憶體
- 程式間通訊---共享記憶體記憶體
- linux程式間的通訊(C): 共享記憶體Linux記憶體
- 程式間通訊之共享記憶體記憶體
- linux程式間通訊-----管道總結例項Linux
- Linux 程式間通訊之System V 訊號量Linux
- linux 程式間通訊之System V 訊息佇列Linux佇列
- 程序間通訊(3)-共享記憶體記憶體
- 程式間通訊——基於共享記憶體和訊號量實現共享佇列記憶體佇列
- (原創)[.Net] 程式間通訊框架(基於共享記憶體)——SimpleMMF框架記憶體
- Linux 下的程式間通訊:共享儲存Linux
- linux 程式間通訊之System V 訊息佇列 www.weiboke.onlineLinux佇列
- 程式間的八種通訊方式----共享記憶體是最快的 IPC 方式記憶體
- linux程式間通訊-----訊號總結Linux
- linux程式間通訊(IPC)小結Linux
- “Linux程式設計”小結(程式間通訊)Linux程式設計
- php實現共享記憶體程式通訊函式之_shmPHP記憶體函式
- Oracle例項的程式結構和記憶體結構Oracle記憶體
- oracle 例項記憶體結構Oracle記憶體
- Linux程式間通訊Linux
- 程式間通訊——LINUXLinux
- ORACLE例項的程式結構和記憶體結構(轉)Oracle記憶體
- 畫江湖之 PHP 多程式開發 【程式中如何通訊 共享記憶體】PHP記憶體
- 畫江湖之 PHP 多程式開發 [程式中如何通訊 共享記憶體]PHP記憶體
- Linux程式間通訊-eventfdLinux
- Linux程式間通訊1Linux
- Linux程式間通訊2Linux
- 程式間通訊機制(管道、訊號、共享記憶體/訊號量/訊息佇列)、執行緒間通訊機制(互斥鎖、條件變數、posix匿名訊號量)記憶體佇列執行緒變數
- C# .Net 多程式同步 通訊 共享記憶體 記憶體對映檔案 Memory MappedC#記憶體APP
- 什麼是程式間通訊?Linux程式間通訊有幾種方式?Linux
- 程式間通訊是什麼?Linux程式間通訊有幾種方式?Linux
- SQL 視訊整體總結SQL