设为首页 加入收藏

TOP

进程间通信(IPC)(二)
2023-07-23 13:34:36 】 浏览:71
Tags:程间通 IPC
AT - 创建,不存在则创建 存在则获取(除非指定IPC_EXCL) 如果IPC_CREAT需要给定共享内存的权限(mode) IPC_CREAT|0644 IPC_EXCL - 排斥,和IPC_CREAT按位域,如果共享内存已经存在则失败 成功返回共享内存的标识,失败返回-1 */ //2.加载共享内存 将进程中的虚拟内存地址映射到共享内存中 void* shmat(int shmid,void *shmaddr,int shmflg); /* A.将shmid(shmget的返回值)参数所标识的共享内存,映射到调用进程的地址空间 B.可以通过参数shmaddr(进程中的虚拟地址)人为指定映射地址,也可以将参数置为NULL,由系统自动选择 C.参数shmflg标识: 0 - 以读写方式使用共享内存 SHM_RDONLY - 以只读方式使用共享内存 SHM_RND - 只在shmaddr参数非NULL时才起作用,表示对shmaddr参数向下取内存页的整数倍作为映射地址 成功返回映射地址,失败返回-1(0XFFFFFFF) 如果加载成功,内核将该共享内存的加载计数加1(共享内存由内核维护,记录有多少个进程加载了该共享内存) */ //3.卸载共享内存 int shmdt(const void *shmaddr); /* 将参数shmaddr所指向加载的共享内存映射从调用进程的取消映射 成功返回0,失败返回-1 如果卸载成功,内核会将该共享内存的加载计数减1 */ //4.销毁/控制共享内存 int shmctl(int shmid,int cmd,struct shmid_ds* buf); /* A.参数shmid是shmget的返回值 是对shmid所标识的共享内存进行删除/获取共享内存的信息 B.cmd取值 IPC_STAT - 获取共享内存的属性,通过buf参数输出 IPC_SET - 设置共享内存的属性,通过buf参数输入,仅三个属性可设置 shm_perm.uid 用户ID shm_perm.gid 组ID shm_perm.mode 权限 IPC_RMID - 标记删除共享内存 并非真正删除共享内存,只是做一个删除标记,禁止其被继续加载,但已有加载依然保留。 只有当该共享内存的加载计数为0且使用IPC_RMID时才真正被删除 成功返回0 失败返回-1 */ struct shmid_ds{ struct ipc_perm shm_perm; //所有者及权限 size_t shm_segsz; //共享内存大小(以字节为单位) time_t shm_atime; //最后加载时间 time_t shm_dtime; //最后卸载时间 time_t shm_ctime; //最后修改时间 pid_t shm_cpid; //创建共享内存的进程ID pid_t shm_lpid; //最后加载、卸载进程的ID shmatt_t shm_nattch; //当前加载计数 ... }; struct ipc_perm{ key_t __key; //键值 uid_t uid; //有效属主ID gid_t gid; //有效属组ID uid_t cuid; //有效创建者ID gid_t cgid; //有效创建组ID unsigned short mode; //权限 unsigned short __seq;//序列号 };
#ipcs -m       #查看当前系统的共享内存
#ipcrm -m shmid    #删除指定的共享内存
  • 消息队列

    基本特点
    • 消息队列是由一个系统内核负责存储和管理,并通过消息队列标识引用的数据链表
    • 可以通过msgget函数创建一个新的消息队列 ,或者获取一个已经存在的消息队列
    • 通过msgsnd函数向消息队列的后端追加消息(需要把消息从用户空间拷贝到内核空间)
    • 通过msgrcv函数从消息队列的前端按要求提取消息(需要把消息从内核空间拷贝到用户空间)
    • 消息队列中的每个消息除了消息本身数据以外,还包含消息类型和数据长度
    • 内核为每个消息队列 ,维护一个msqid_ds结构体形式的消息队列对象
    #include <sys/msg.h>
    
    //msgget 创建或者获取消息队列 
    int msgget(key_t key,int msgflg);
    /*
    	A.该函数以参数key作为键值创建消息队列,如果存在则获取消息队列
    	B.msgflg标识
    		0		- 获取,不存在即失败
    		IPC_CREAT	- 创建,不存在则创建,已存在则获取,除非      创建时需要给定权限 IPC|0644
    		IPC_EXCL	- 排斥,创建时如果已经存在则创建失败
    	成功返回消息队列标识,失败返回-1
    */
    //msgsnd向消息队列发送消息
    int msgsnd(int msgqid,const void *msgp,size_t msgsz,int msgflg);
    /*
    	A. msgqid 消息队列的标识  msgget函数的返回值
    	B. msgp参数是一个指针,指针指向一块内存,内存中包含消息类型和消息数据
    		内存中的前4/8个字节必须是一个大于0的整数,代表消息类型,其后紧跟消息数据
    		消息数据的字节长度用msgsz参数表示     注意:msgsz长度并不包含消息类型4/8个字节
                +------------+--------------------+
        msgp--> |消息类型(>0) | 消息数据             |
                +------------+--------------------+
                |<-4/8Byte-> |<----msgsz--------->|
        
    	C.若内核中消息队列缓冲区有足够的空闲空间,则此函数会将消息拷入缓冲区并立即返回0,表示发送成功,否则此函数会阻塞,直到内核中的消息队列缓冲区有足够的空闲空间为止(比如有消息被接收)
    	D.若msgflg参数包含IPC_NOWAIT位,则当内核中的消息队列没有足够空闲空间时,此函数不会阻塞,而是直接返回-1,且errno设置为EAGAIN
    	成功返回0  失败返回-1
    */
    
    //msgrcv 从消息队列中接收消息
    ssize_t msgrcv(int msgqid,void *msgp,size_t msgsz,long msgtype,int msgflg);
    /*
    	A.msgqid 消息队列标识,msgget函数的返回值
    	B.msgp指针指向一个包含消息类型(4byte)和消息数据的内存块,用于存储消息类型和消息数据本身
    	C.msgsz参数用来标明消息数据缓冲区字节大小   msgp指针指向的内存块的大小-4/8byte
    	D.若所接收到的消息字节数据大于msgsz参数,即消息太长
    	E.如果msgflg参数中包含MSG_NOERROR位,则消息太长会被截取msgsz字节返回,剩余部分会被丢弃
    		如果msgflg参数不包含MSG_NOERROR五个,消息太长时,不会对该消息做任何处理,直接返回-1,且errno设置为E2BIG 
    	F.msgtype参数表示期望接收哪类消息
    		msgtype = 0  - 返回消息队列中的第一条消息
    		m
  • 首页 上一页 1 2 3 4 下一页 尾页 2/4/4
    】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
    上一篇cobbler 下一篇Linux:进程模型和进程管理

    最新文章

    热门文章

    Hot 文章

    Python

    C 语言

    C++基础

    大数据基础

    linux编程基础

    C/C++面试题目