linux shmget shmctl

shmget
int shmget(key_t key, size_t size, int flag);
key: 標識符的規則
size:共享存儲段的字節數
flag:讀寫的權限
返回值:成功返回共享存儲的id,失敗返回-1

key_t key
-----------------------------------------------
??? key標識共享內存的鍵值: 0/IPC_PRIVATE。?當key的取值為IPC_PRIVATE,則函數shmget()將創建一塊新的共享內存;如果key的取值為0,而參數shmflg中設置了IPC_PRIVATE這個標志,則同樣將創建一塊新的共享內存。


??? 在IPC(InterProcess Communication)的通信模式下,不管是使用消息隊列還是共享內存,甚至是信號量,每個IPC的對象(object)都有唯一的名字,稱為“鍵”(key)。通過“鍵”,進程能夠識別所用的對象。“鍵”與IPC對象的關系就如同文件名稱之于文件,通過文件名,進程能夠讀寫文件內的數據,甚至多個進程能夠共用一個文件。而在IPC的通訊模式下,通過“鍵”的使用也使得一個IPC對象能為多個進程所共用。
??? Linux系統中的所有表示System V中IPC對象的數據結構都包括一個ipc_perm結構,其中包含有IPC對象的鍵值,該鍵用于查找System V中IPC對象的引用標識符。如果不使用“鍵”,進程將無法存取IPC對象,因為IPC對象并不存在于進程本身使用的內存中。
??? 通常,都希望自己的程序能和其他的程序預先約定一個唯一的鍵值,但實際上并不是總可能的成行的,因為自己的程序無法為一塊共享內存選擇一個鍵值。因此,在此把key設為IPC_PRIVATE,這樣,操作系統將忽略鍵,建立一個新的共享內存,指定一個鍵值,然后返回這塊共享內存IPC標識符ID。而將這個新的共享內存的標識符ID告訴其他進程可以在建立共享內存后通過派生子進程,或寫入文件或管道來實現。


int size(單位字節Byte)
-----------------------------------------------
??? size是要建立共享內存的長度。所有的內存分配操作都是以頁為單位的。所以如果一段進程只申請一塊只有一個字節的內存,內存也會分配整整一頁(在i386機器中一頁的缺省大小PACE_SIZE=4096字節)這樣,新創建的共享內存的大小實際上是從size這個參數調整而來的頁面大小。即如果size為1至4096,則實際申請到的共享內存大小為4K(一頁);4097到8192,則實際申請到的共享內存大小為8K(兩頁),依此類推。


int shmflg
-----------------------------------------------
??? shmflg主要和一些標志有關。其中有效的包括IPC_CREAT和IPC_EXCL,它們的功能與open()的O_CREAT和O_EXCL相當。
????IPC_CREAT?? 如果共享內存不存在,則創建一個共享內存,否則打開操作。
????IPC_EXCL??? 只有在共享內存不存在的時候,新的共享內存才建立,否則就產生錯誤。

??? 如果單獨使用IPC_CREAT,shmget()函數要么返回一個已經存在的共享內存的操作符,要么返回一個新建的共享內存的標識符。如果將IPC_CREAT和IPC_EXCL標志一起使用,shmget()將返回一個新建的共享內存的標識符;如果該共享內存已存在,或者返回-1。IPC_EXEL標志本身并沒有太大的意義,但是和IPC_CREAT標志一起使用可以用來保證所得的對象是新建的,而不是打開已有的對象。對于用戶的讀取和寫入許可指定SHM_R和SHM_W,(SHM_R>3)和(SHM_W>3)是一組讀取和寫入許可,而(SHM_R>6)和(SHM_W>6)是全局讀取和寫入許可。

需要注意的是,使用參數要加上 | 0666 作為校驗,在有些Linux系統中,如果不加此校驗,則不能順利獲取共享空間的值(如Ubuntu)。此外,有兩個常用參數,一般要同時出現,他們是:S_IRUSH | S_IWUSR 。由于這兩個參數非常常用,程序員一般做這樣的操作
  #define PERM S_IRUSR | S_IWUSR | IPC_CREAT
  這樣一來,第三個參數就可以直接用PERM來表示了!

返回值
-----------------------------------------------
成功返回共享內存的標識符;不成功返回-1,errno儲存錯誤原因。
??? EINVAL??????? 參數size小于SHMMIN或大于SHMMAX。
??? EEXIST??????? 預建立key所致的共享內存,但已經存在。
??? EIDRM???????? 參數key所致的共享內存已經刪除。
??? ENOSPC??????? 超過了系統允許建立的共享內存的最大值(SHMALL )。
??? ENOENT??????? 參數key所指的共享內存不存在,參數shmflg也未設IPC_CREAT位。
??? EACCES??????? 沒有權限。
??? ENOMEM??????? 核心內存不足。


struct shmid_ds
-----------------------------------------------
??? shmid_ds數據結構表示每個新建的共享內存。當shmget()創建了一塊新的共享內存后,返回一個可以用于引用該共享內存的shmid_ds數據結構的標識符。

include/linux/shm.h

??? struct shmid_ds {?
??????? struct ipc_perm??? shm_perm;????? /* operation perms */?
??????? int??????????????? shm_segsz;???? /* size of segment (bytes) */?
??????? __kernel_time_t??? shm_atime;???? /* last attach time */?
??????? __kernel_time_t??? shm_dtime;???? /* last detach time */?
??????? __kernel_time_t??? shm_ctime;???? /* last change time */?
??????? __kernel_ipc_pid_t shm_cpid;????? /* pid of creator */?
??????? __kernel_ipc_pid_t shm_lpid;????? /* pid of last operator */?
??????? unsigned short???? shm_nattch;??? /* no. of current attaches */?
??????? unsigned short???? shm_unused;??? /* compatibility */?
??????? void?????????????? *shm_unused2; /* ditto - used by DIPC */?
??????? void?????????????? *shm_unused3; /* unused */?
??? };


struct ipc_perm
-----------------------------------------------
??? 對于每個IPC對象,系統共用一個struct ipc_perm的數據結構來存放權限信息,以確定一個ipc操作是否可以訪問該IPC對象。

??? struct ipc_perm {?
??????? __kernel_key_t?? key;?
??????? __kernel_uid_t?? uid;?
??????? __kernel_gid_t?? gid;?
??????? __kernel_uid_t?? cuid;?
??????? __kernel_gid_t?? cgid;?
??????? __kernel_mode_t mode;?
??????? unsigned short?? seq;?
};
//----------------------------------------

shmat
void *shmat(int shmid, const void *addr, int flag);
shmid:共享存儲的id
addr:一般為0,表示連接到由內核選擇的第一個可用地址上,否則,如果flag沒有指定SHM_RND,則連接到addr所指定的地址上,如果flag為SHM_RND,則地址取整
flag:如前所述,一般為0
返回值:如果成功,返回共享存儲段地址,出錯返回-1
共享存儲器的執行方式是將一個儲存器區段標記為共用,這時各進程可以把這個區段映射到該進程本身的虛擬地址里。建立共享存儲器可通過shmget系統調用,shmget執行后,核心程序就保留一塊指定大小的空間,同時關于此共享存儲器的一切數據,如區段的長度,區段的存取權,區段建立者的進程識別碼等存入一個叫shmid_ds的結構。現在共享存儲器雖然已經建立了,可是仍無法連上它,這時就須通過shmat系統調用得到一個指向共享存儲器基址的指針,通過此指針,就可以如同于操作一般存儲器似的取用共享存儲器。shmdt進行相反的工作,用來脫離已連上的共享存儲器。


shmdt
int shmdt(void *addr);
addr:共享存儲段的地址,以前調用shmat時的返回值
shmdt將使相關shmid_ds結構中的shm_nattch計數器值減1

當一個進程不再需要共享內存段時,它將調用shmdt()系統調用取消這個段,但是,這并不是從內核真正地刪除這個段,而是把相關shmid_ds結構的?shm_nattch域的值減1,當這個值為0時,內核才從物理上刪除這個共享段


shmctl
int shmctl(int shmid,int cmd,struct shmid_ds *buf)
shmid:共享存儲段的id
cmd:一些命令

IPC_STAT 得到共享內存的狀態
????????IPC_SET 改變共享內存的狀態
????????IPC_RMID 刪除共享內存?

IPC_RMID?命令實際上不從內核刪除一個段,而是僅僅把這個段標記為刪除,實際的刪除發生在最后一個進程離開這個共享段時。?

請注意,共享內存不會隨著程序結束而自動消除,要么調用shmctl刪除,要么自己用手敲命令去刪除,否則永遠留在系統中。

?

實例:

?

C代碼??收藏代碼
  1. #include?<stdio.h>??
  2. #include?<string.h>??
  3. #include?<stdlib.h>??
  4. #include?<errno.h>??
  5. #include?<unistd.h>??
  6. #include?<sys/stat.h>??
  7. #include?<sys/types.h>??
  8. #include?<sys/ipc.h>??
  9. #include?<sys/shm.h>??
  10. #define?PERM?S_IRUSR|S_IWUSR??
  11. ??
  12. int?main(int?argc,char?**argv){??
  13. ????int?shmid;??
  14. ????char?*p_addr,*c_addr;??
  15. ????if(argc!=2){??
  16. ????????fprintf(stderr,"Usage:%s\n\a",argv[0]);??
  17. ????????exit(1);??
  18. ????}??
  19. ??
  20. ????if((shmid=shmget(IPC_PRIVATE,1024,PERM))==-1){??
  21. ????????fprintf(stderr,"Create?Share?Memory?Error:%s\n\a",strerror(errno));??
  22. ????????exit(1);??
  23. ????}??
  24. ??
  25. ????if(fork()){??
  26. ????????p_addr=shmat(shmid,0,0);??
  27. ????????memset(p_addr,'\0',1024);??
  28. ????????strncpy(p_addr,argv[1],1024);??
  29. ????????exit(0);??
  30. ????}else{??
  31. ????????c_addr=shmat(shmid,0,0);??
  32. ????????printf("Client?get?%s",c_addr);??
  33. ????????exit(0);??
  34. ????}??
  35. }??

?這個程序是父進程將參數寫入到共享內存,然后子進程把內容讀出來.最后我們要使用ip

crm 釋放資源的.先用ipcs 找出ID 然后用ipcrm shm ID 刪除.

轉載于:https://www.cnblogs.com/jkred369/p/6733141.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/252860.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/252860.shtml
英文地址,請注明出處:http://en.pswp.cn/news/252860.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

java控制臺輸入輸出總結

一、控制臺輸入&#xff1a; 1.最常用&#xff1a;Scanner public static void main(String[] args) { System.out.println("請輸入數據:"); Scanner scan new Scanner(System.in); String read scan.nextLine(); System.out.println("輸入的數據為:"…

伯克利開源工具庫RLib現已支持大規模多智能體強化學習

AI前線導讀&#xff1a;近日&#xff0c;UC伯克利的研究團隊RISELab在其Github的項目Ray Rlib 0.6.0中添加了面向多智能體強化學習&#xff08;multi-agent Reinforcement Learning&#xff09;的支持。本文由團隊成員Eric Liang首發于RISELab團隊主頁&#xff0c;AI前線翻譯整…

相機電子快門和機械快門有什么區別

https://zhidao.baidu.com/question/9178007.html

Long

而由于javascript數字的最大值2的53次方-1&#xff0c;以及PHP的數字處理能力&#xff0c;比如number_format(9027199254740993, 0, , )轉載于:https://www.cnblogs.com/sfsdst/p/6734083.html

操作系統實驗以及課程設計

趁沒人&#xff0c;當個小白來偷偷摸摸補一下操作系統的課程&#xff0c;羞反正操作系統斷斷續續的看了一點了&#xff0c;主要是偏linux的。FreeBSD的實現&#xff0c;操作系統概念&#xff0c;30天自制操作系統等。Linux的話命令用的還行&#xff0c;沒有很深入的搞。看操作系…

關于星光級和低照度你了解多少?

http://www.tpy888.cn/news/201607/22/89214.html

AI界的妖風

最近一篇文章https://zhuanlan.zhihu.com/p/50948707深度學習碰上古文獻&#xff0c;西南大學提出基于CNN的古彝文識別方法 我預計不久之后就會出現一個現象&#xff1a;不光有彝族文字識別&#xff0c;還有蒙文識別&#xff0c;藏文識別&#xff0c;苗文識別 然后各位教授一起…

poj1936

非連續子串匹配題&#xff0c;直接模擬 /** \brief poj 1936** \param date 2014/8/5* \param state AC* \return memory 804k time 0ms**/#include <iostream> #include <fstream> #include <cstring>using namespace std;const int MAXN100000; char s[MAX…

Process和ProcessBuilder入門【原】

ProcessBuilder優點 ProcessBuilder(XXX).start()和Runtime.exec(XXX)功能相同,主要優點在使用過程中感受有: 前者是jdk1.5后的新方式配置環境變量時更優雅對當前目錄的控制也更合理錯誤流重定向特別方便 進程控制更簡潔ProcessTool.java package test;import java.io.Buffered…

如何簡單理解光圈大小對手機攝影的影響?

你&#xff0c;準備好參加今夏的朋友圈攝影大賽了嗎&#xff1f; 現在的天氣有多熱&#xff0c;誰出門誰知道&#xff01;出去玩還要背一臺單反&#xff0c;絕對可以說是一種折磨了。但是&#xff0c;如果你擁有一臺大光圈的手機&#xff0c;一樣可以在朋友圈脫穎而出。 那么…

基于centos6.7的docker私有倉庫搭建

2019獨角獸企業重金招聘Python工程師標準>>> 1 倉庫配置https認證 cd /etc/docker/ mkdir certs [rootdocker01 docker]# openssl req -newkey rsa:4096 -nodes -sha256 -keyout certs/docker01.key -x509 -days 365 -out certs/docker01.crt 填好相應的簡稱及email…

第十周軟件工程作業-每周例行報告

一、PSP T名稱C內容ST開始時間ED結束時間中斷時間/min實際時間/min會議第一次Scrum會議11月17日16:0011月17日16:30030第二次Scrum會議11月18日15:0011月18日15:30030第三次Scrum會議11月19日17:0011月19日17:30030第四次Scrum會議11月20日11:3511月20日12:15040第五次Scrum會議…

卷簾快門與全局快門的區別

https://wenku.baidu.com/view/2f0c8da0ce2f0066f5332283.html

MAVEN下載和安裝

1.maven的下載 下載鏈接http://maven.apache.org/download.cgi從該網站下載最新版本 2.maven的安裝 電腦上需要安裝JDK環境&#xff0c;需要安裝JDK7以上的版本。下載之后進行解壓&#xff0c;將maven解壓到不含中文和空格的一個目錄 maven目錄結構bin目錄&#xff1a;mvn.bat、…

洛谷 P3391 【模板】文藝平衡樹

題目背景 這是一道經典的Splay模板題——文藝平衡樹。 題目描述 您需要寫一種數據結構&#xff0c;來維護一個有序數列&#xff0c;其中需要提供以下操作&#xff1a;翻轉一個區間&#xff0c;例如原有序序列是5 4 3 2 1&#xff0c;翻轉區間是[2,4]的話&#xff0c;結果是5 2 …

CCD/CMOS靶面尺寸型號標準

傳感器尺寸指的是感光器對角線尺寸&#xff0c;1/1.7英寸&#xff08;14.8毫米&#xff0d;&#xff0d;導向管尺寸&#xff09;大于1/2.3英寸&#xff08;10.95毫米&#xff0d;&#xff0d;&#xff0d;導向管尺寸&#xff09;.采用同種技術水平的感光器&#xff0c;肯定是單…

分布式學習基礎知識

網絡通訊&#xff0c;網絡是分布式的基礎&#xff0c;對分布式的理解建立在對網絡的理解上&#xff0c;包括&#xff1a; OSI模型的7層TCP/IP&#xff0c;DNS&#xff0c;NATHTTP&#xff0c;SPDY/HTTP2Telnet網絡編程&#xff0c;是通過程序在多個主機之間通信。包括&#xff…

django中FastDFS客戶端與自定義文件存儲系統

什么是FastDFSFastDFS 是用 c 語言編寫的一款開源的分布式文件系統。FastDFS 為互聯網量身定制&#xff0c; 充分考慮了冗余備份、負載均衡、線性擴容等機制&#xff0c;并注重高可用、高性能等指標&#xff0c;使用 FastDFS 很容易搭建一套高性能的文件服務器集群提供文件上傳…

新近碰到的病毒(TR.Spy.Babonock.A)

先來段Microsoft的說明&#xff1a; Worm:Win32/Babonock.A Alert level: Severe Detected with Windows Defender Antivirus Also detected as:Worm/Win32.AutoIt (AhnLab)Trojan-Spy.Win32.AutoIt.p (Kaspersky)Worm/Autoit.ANVE (AVG)TR/Spy.Babonock.A (Avira)Win32/Autoit…

鏡頭基本參數

非常好的文章 &#xff0c;下載不了&#xff0c;但是會經常閱讀。 https://wenku.baidu.com/view/47a7deddee06eff9aff8074e.html?rec_flagdefault&sxts1529650964474