日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux IPC实践(9) --System V共享内存

發布時間:2025/3/17 linux 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux IPC实践(9) --System V共享内存 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

共享內存API

#include <sys/ipc.h> #include <sys/shm.h>int shmget(key_t key, size_t size, int shmflg); void *shmat(int shmid, const void *shmaddr, int shmflg); int shmdt(const void *shmaddr); int shmctl(int shmid, int cmd, struct shmid_ds *buf); //System V 共享內存基本數據結構 struct shmid_ds {struct ipc_perm shm_perm; /* Ownership and permissions: System V IPC所共有的數據結構 */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 */... };

shmget

int shmget(key_t key, size_t size, int shmflg);

? ?創建共享內存,并將該內存的內容初始化為0;?

? ?打開一個已經存在共享內存,?如果打開時不知道共享內存的大小,?可以將size指定為0,?shmflg可以指定為0(按照默認的權限打開);? ??

參數:

? ?key:這個共享內存段名字;

? ?size:共享內存大小(bytes);

? ?shmflg:用法類似msgget中的msgflg參數;

返回值:

? ?成功返回一個非負整數,即該共享內存段的標識碼;失敗返回-1

/**示例: 創建并打開一個共享內存 **/ int main(int argc,char **argv) {const int SHM_SIZE = 1024;int shmid = shmget(0x1234, SHM_SIZE, 0666|IPC_CREAT);if (shmid == -1)err_exit("shmget error");cout << "share memory get success" << endl; }

shmat

void *shmat(int shmid, const void *shmaddr, int shmflg);

? ?連接到本進程地址空間,?成功連接之后,?對該內存的操作就與malloc來的一塊內存非常類似了,?而且如果這塊內存中有數據,?則就可以直接將其中的數據取出來!!

參數:

? ?shmaddr:指定連接的地址(推薦使用NULL)

? ?shmflg:一般指定為0,?表示可讀,可寫;?而它的另外兩個可能取值是SHM_RND和SHM_RDONLY(見下)

返回值:

? ?成功返回一個指針,指向共享內存起始地址;失敗返回(void?*)?-1


shmaddr與shmflg組合說明

shmaddr為NULL

Linux內核自動為進程連接到進程的內存(推薦使用)

shmaddr不為NULL且shmflg無SHM_RND標記

以shmaddr為連接地址

shmaddr不為NULL且shmflg設置了SHM_RND標記

連接的地址會自動向下調整為SHMLBA的整數倍;

公式:shmaddr?-?(shmaddr?%?SHMLBA)

SHMLBA為內存頁面的大小(4K)

shmflg=SHM_RDONLY

只讀共享內存,?不然的話就是可讀,可寫的,?注意:?此處沒有可讀,可寫這個概念

?

shmdt

int shmdt(const void *shmaddr);

參數:

? ?shmaddr:?由shmat所返回的指針

注意:將共享內存段與當前進程脫離不等于刪除共享內存段

/** 示例: 將數據寫入/讀出共享內存 程序write: 將數據寫入共享內存 程序read: 將數據讀出共享內存(當然, 可以讀取N多次) **/ //write程序 struct Student {char name[26];int age; }; int main(int argc,char **argv) {int shmid = shmget(0x1234, sizeof(Student), 0666|IPC_CREAT);if (shmid == -1)err_exit("shmget error");// 以可讀, 可寫的方式連接該共享內存Student *p = (Student *)shmat(shmid, NULL, 0);if (p == (void *)-1)err_exit("shmat error");strcpy(p->name, "xiaofang");p->age = 22;shmdt(p); } //read程序 int main(int argc,char **argv) {int shmid = shmget(0x1234, 0, 0);if (shmid == -1)err_exit("shmget error");// 以只讀方式連接該共享內存Student *p = (Student *)shmat(shmid, NULL, 0);if (p == (void *)-1)err_exit("shmat error");// 直接將其中的內容打印輸出cout << "name: " << p->name << ", age: " << p->age << endl;shmdt(p); }

shmctl

int shmctl(int shmid, int cmd, struct shmid_ds *buf);

設置/獲取共享內存屬性

參數:

? ?cmd:將要采取的動作(三個取值見下)

? ?buf:指向一個保存著共享內存的模式狀態和訪問權限的數據結構

System?V共享內存小結:

? ?1.共享內存被別的程序占用,則刪除該共享內存時,不會馬上刪除(引用計數計數);

? ?2.此時會出現一個現象:該共享內存的key變為0x00000000,變為私有;

? ?3.此時還可以讀,但必須還有辦法獲取該共享內存的ID(shmid),因為此時試圖通過該共享內存的key獲取該共享內存,是白費的!

/** 示例: 刪除共享內存 **/ int main(int argc,char *argv[]) {int shmid = shmget(0x1234, 0, 0);if (shmid == -1)err_exit("shmget error");if (shmctl(shmid, IPC_RMID, NULL) == -1)err_exit("shmctl IPC_RMID error");cout << "share memory remove success" << endl; }

總結

以上是生活随笔為你收集整理的Linux IPC实践(9) --System V共享内存的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。