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.mzph.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