模型#include #include #include ftok() //获取key值 msgget() //创建/获取消息队列 msgsnd()/msgrcv() //发消息到消息队列/从消息队列收信息 msgctl() //删除消息队列 ftok()//获取key值, key值是system v ipc的标识符,成功返回key,失败返回-1设errno//同pathname+同 proj_id==>同key_t;key_t ftok(const char *pathname, int proj_id);pathname :文件名
proj_id: 1~255的一个数,表示project_id
key_t key=ftok(.,100); //“.”就是一个存在且可访问的路径, 100是假设的proj_id if(-1==key) perror(ftok),exit(-1);msgget()//创建/获取消息队列,成功返回shmid,失败返回-1int msgget(key_t key, int msgflg); //attention:用int msqid=msgget()比较好看msgflg:具体的操作标志
ipc_creat 若不存在则创建, 需要在msgflg中"|权限信息"; 若存在则打开ipc_excl若存在则创建失败0 获取已经存在的消息队列消息队列的容量由msg_qbytes控制,在消息队列被创建的过程中,这个大小被初始化为msgmnb,这个限制可以通过msgctl()修改
int msqid=msgget(key,ipc_creat|ipc_excl|0664);if(-1==msqid) perror(msgget),exit(-1);msgsnd()//向指定的消息队列发送指定的消息,如果消息队列已经满了,默认的行为是堵塞,直到队列有空间容纳新的消息,成功返回0,失败返回-1设errnoint msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);msqid msgget()返回的消息队列的id
msgp消息的的首地址, 消息的参考数据类型如下
struct msgbuf { long mtype; /* message type, must be > 0 */ //消息的类型 char mtext[1]; /* message data */ //消息的内容};attention:the mtext field is an array (or other structure) whose size is specified by msgsz, a nonnegative integer value. msgsz消息的大小, 该参数用于指定消息内容的大小, 不包括消息的类型。只能sizeof(msgbuf.mtext),不能sizeof(msgbuf)
msgflg发送的标志, 默认给0即可
msg msg1={1,hello};//消息的类型是1,内容是helloint res=msgsnd(msqid,&msg2,sizeof(msg2.buf),0);if(-1==res) perror(msgsnd),exit(-1);msgrcv()//向指定的消息队列取出指定的消息,成功返回实际接受到的byte数,失败返回-1设errnossize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);msqid: 消息队列的id(returned by msgget)
msgp: 存放接收到消息的缓冲区首地址
msgsz: 消息的最大大小, 不包括消息的类型==>只能sizeof(msgbuf.mtext),不能sizeof(msgbuf)
如果消息的长度>msgsz且msgflg里有msg_noerror,则消息会被截断,被截断的部分会丢失如果消息的长度>msgsz且msgflg里没有msg_noerror,那么会出错,报e2big。msgtyp: 消息的类型
0:读取消息队列中的第一个消息>0:读取消息队列中第一个type为msgtype的消息, 除非msg_flg里有msg_except,此时队列中的第一个不是msgtyp的消息会被读取<0读取消息队列中type<=|msgtype|的消息, 这里再优先读取最小的msgflg: 发送的标志, 默认给0即可
msg msg1;int res=msgrcv(msqid,&msg1,sizeof(msg1.buf),1,0);if(-1==res) perror(msgrcv),exit(-1);msgctl()// 消息操作,成功返回0,失败返回-1设errnoint msgctl(int msqid, int cmd, struct msqid_ds *buf);msqid :消息队列的id,由msgget()
buf 结构体指针
struct msqid_ds { struct ipc_perm msg_perm; /* ownership and permissions */ time_t msg_stime; /*time of last msgsnd(2) */ time_t msg_rtime; /* time of last msgrcv(2) */ time_t msg_ctime; /* time of last change */ unsigned long __msg_cbytes; /* current number of bytes in queue (nonstandard) */ msgqnum_t msg_qnum; /* current number of messages in queue */ msglen_t msg_qbytes; /* maximum number of bytes allowed in queue */ pid_t msg_lspid; /* pid of last msgsnd(2) */ pid_t msg_lrpid; /* pid of last msgrcv(2) */};struct ipc_perm { key_t __key; /* key supplied to msgget(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 */ unsigned short __seq; /* sequence number */};cmd
ipc_stat从内核相关结构体中拷贝消息队列相关的信息到buf指向的结构体中ipc_set把buf指向的结构体的内容写入到内核相关的结构体中,同时更显msg_ctimer成员,同时以下成员也会被更新:msg_qbytes, msg_perm.uid, msg_perm.gid, msg_perm.mode。调用队列的进程的effective uid必须匹配队列所有者或创建者的msg_perm.uid或msg_perm.cuid或者该进程拥有特权级别,ipc_rmid立即销毁消息队列,唤醒所有正在等待读取或写入该消息队列进程,调用的进程的uid必须匹配队列所有者或创建者或者该进程拥有足够的特权级别ipc_info (linux-specific)返回整个系统对与消息队列的限制信息到buf指向的结构体中
//_gnu_source//struct msginfo { int msgpool;/*size in kibibytes of buffer pool used to hold message data; unused within kernel*/ int msgmap; /*maximum number of entries in message map; unused within kernel*/ int msgmax; /*maximum number of bytes that can be written in a single message*/ int msgmnb; /*maximum number of bytes that can be written to queue; used to initialize msg_qbytes during queue creation*/ int msgmni; /*maximum number of message queues*/ int msgssz; /*message segment size; unused within kernel*/ int msgtql; /*maximum number of messages on all queues in system; unused within kernel*/ unsigned short int msgseg; /*maximum number of segments; unused within kernel*/};int res=msgctl(msqid,ipc_rmid,null);if(-1==res)perror(msgctl),exit(-1);例子//sys v ipc msg#include#include#include#include#includetypedef struct{ long mtype; //消息的类型 char buf[20]; //消息的内容}msg;int msqid; //使用全局变量,这样就可以在fa中使用msqid了void fa(int signo){ printf(deleting..\n); sleep(3); int res=msgctl(msqid,ipc_rmid,null); if(-1==res) perror(msgctl),exit(-1); exit(0);}int main(){ //ftok() key_t key=ftok(.,150); if(-1==key) perror(ftok),exit(-1); printf(key%#x\n,key); //msgget() msqid=msgget(key,ipc_creat|ipc_excl|0664); if(-1==msqid) perror(msgget),exit(-1); printf(msqid%d\n,msqid); //msgsnd() msg msg1={1,hello};//消息的类型是1,内容是hello msg msg2={2,world}; int res=msgsnd(msqid,&msg2,sizeof(msg2.buf),0); if(-1==res) perror(msgsnd),exit(-1); res=msgsnd(msqid,&msg1,sizeof(msg1.buf),0); if(-1==res) perror(msgsnd),exit(-1); //msgctl() //ctrl+c delete msq printf(press ctrl+c to delete msq\n); if(sig_err==signal(sigint,fa)) perror(signal),exit(-1); while(1); return 0;}
北桥芯片详解
电流互感器的反接线介绍
熟练掌握2%的Excel关键功能,每年都能轻松省出一个年假
法拉电容对汽车有用吗_汽车法拉电容的作用
如何在JMAG-Designer中创建JMAG-RT模型并进行控制仿真
Linux IPC System V 消息队列
金山云的日照高新智慧谷物联网平台解决方案荣获“2019中国智慧城市优秀解决方案奖”
LCD1604接口定义,LCD1604基本参数
适合下一代蜂窝网络的优化芯片解决方案
美国“毅力号”火星车搭载与iMac G3同款CPU
RF功率测量系统电路功能与优势
基于51单片机的智能恒温箱设计
西门子推出公共直流快速充电器
5G是否会冲击微信支付宝
米粉看小米6曝光?顶配双曲面屏2999元
Aruba推出Aruba ESP边缘服务平台,问题判断准确率高达95%
北极圈附近的地区在特殊的温度和纬度下,无人车是如何实现定位的
视频是“N千兆”的天然纽带,运营商从三方面推动网络千兆化
北斗卫星导航系统布局完成,23颗卫星的电源系统皆由上海研制
ChatGPT将为数据治理带来哪些改变?