建设银行学习网站,女生做网站编辑好还是,企业组网方案,wordpress 门户 主题消息队列#xff08;也叫做报文队列#xff09;是一个消息的链表。可以把消息看作一个记录#xff0c;具有特定的格式以及特定的优先级。对消息队列有写权限的进程可以向消息队列中按照一定的规则添加新消息#xff1b;对消息队列有读权限的进程则可以从消息队列中读走消息…消息队列也叫做报文队列是一个消息的链表。可以把消息看作一个记录具有特定的格式以及特定的优先级。对消息队列有写权限的进程可以向消息队列中按照一定的规则添加新消息对消息队列有读权限的进程则可以从消息队列中读走消息。 IPC消息队列资源的限制 IPC消息队列的缺省数为16 每个消息的缺省最大值8192字节 队列中全部信息的缺省大小为16384字节 消息队列的概念和原理
消息队列是一种进程间通信IPC的机制它允许不同进程之间通过消息进行交互。消息队列由内核负责管理可以按顺序发送消息包消息类型和消息内容也可以全双工工作即同时接收和发送消息。消息队列可以不按消息的顺序接收消息因此具有一定的灵活性。
消息队列的应用场景
1.进程间通信消息队列可以用于实现不同进程之间的通信例如一个进程需要向另一个进程发送数据或者通知可以使用消息队列来实现。
2.异步处理当一个进程需要异步处理某些任务时可以使用消息队列来实现。例如一个进程需要等待某个事件发生它可以通过消息队列发送一个消息通知另一个进程该事件已经发生。
3.任务分发在分布式系统中消息队列可以用于任务分发。例如一个进程需要将某个任务分发给其他进程它可以通过消息队列发送任务信息其他进程收到消息后可以按照任务要求进行处理。
4.日志记录消息队列可以用于记录系统日志当一个进程需要记录日志时它可以将日志信息发送到消息队列另一个进程可以实时接收并保存这些日志信息。
消息队列的优缺点
1.优点 - 消息队列允许不同进程之间进行异步通信提高了系统的并发性能。 - 消息队列具有一定的可靠性即使接收进程没有及时处理消息消息队列仍然可以保存消息。 - 消息队列可以实现进程间的解耦降低了进程之间的依赖关系。
2.缺点 - 消息队列的通信效率较低因为消息需要经过内核的复制和传输。 - 消息队列的实现较为复杂需要涉及到进程间通信、内存管理等方面的知识。
消息队列模型 操作消息队列
1、 打开或创建消息队列. 2、 读写操作:消息读写操作非常简单对开发人员来说每个消息都类似如下的数据结构 struct msgbuf{long mtype;char mtext[1];
};mtype 成员代表消息类型从消息队列中读取消息的一个重要依据就是消息的类型 mtext 是消息内容当然长度不一定为 1 。对于 发送消息来说首先预置一个 msgbuf 缓冲区并写入消息类型和内容调用相应的发送函数即可对读取消息来说首先分配这样一个 msgbuf 缓冲区然后把消息读入该缓冲区即 可 3、 获得或设置消息队列属性
• 消息队列 API 共有四个使用时需要包括几个头文件 – #include sys/ types.h – #include sys/ ipc.h – #include sys/ msg.h 消息队列的基本操作—msgget()
• 功能 – 创建 一个新消息队列或 打开 一个存在的队列 • 函数原型 – int msgget ( key_t key , int flag ); • 参数说明 – key 待创建 / 打开队列的键值如果 key 值为 IPC_PRIVATE 则创建一个新的消息队列。 – flag 创建 / 打开方式 • IPC_CREAT 如果存在与当前 key 值相同的消息队列则返回该消息队列 id 。如果不存在则创建一个新的消息队列。 • IPC_EXCL 如果存在与当前 key 值相同的消息队列则返回失败。 • 返回值 – 成功返回消息队列 描述符 否则返回 -1 ftok函数
• ftok 原型 key_t ftok( char * fname, int id )
• 参数 fname指定的文件名(该文件必须是存在而且可以访问的)id是子序号虽然为int但是只有8个比特被使用(0-255)。
• 返回值 当成功执行的时候一个key_t值将会被返回否则 -1 被返回。
• 在一般的 UNIX 实现中是将文件的索引节点号取出前面加上子序号得到 key_t 的返回值。如指定文件的索引节点号为 65538 换算成 16 进制为 0x010002 而你指定的 ID 值为 38 换算成 16 进制为 0x26 则最后的 key_t 返回值为 0x26010002 。 消息队列的基本操作—msgrcv()
• 函数 原型 – ssize_t msgrcv (int msqid , struct msgbuf * msgp , size_t size , long type , int flag ); • 功能 – 该系统调用从 msqid 代表的消息队列中读取一个消息并把消息存储在 msgp 指向的 msgbuf 结构中。 • 参数说明 msqid消息队列描述字描述从哪个消息队列读取消息
msgp消息存储位置
size消息内容的长度(mtext[])
type请求读取的消息类型
• 根据 type 的不同分成三种情况处理 – type0 接收该队列的第一个消息并将它返回给调用者 – type0 接收类型 type 的第一个消息 – type0 接收小于等于 type 绝对值的最低类型的第一个消息 消息队列的基本操作—msgrcv()工作流程
flag规定队列无消息时内核应做的操作
• IPC_NOWAIT 如果现在没有消息调用进程立即返回同时返回 -1 。 • IPC_EXCEPT type0 时使用返回第一个类型不为 type 的消息 • IPC_NOERROR 如果队列中满足条件的消息内容大于所请求的 size 字节则把该消息截断截断部分将丢失。如果没有设置 IPC_NOERROR 而消息又太长则出错返回 E2BIG 此时消息仍留在队列中。 • 调用返回 成功返回读出消息的实际字节数否则返回-1。
• 注意 取消息的时候并不一定按照先进先出的次序取消息可以按照消息的类型字段取消息。
消息队列的基本操作—msgsnd()
• 函数原型 – int msgsnd (int msqid , struct msgbuf * msgp , size_t msgsize , int flag ); • 功能 – 向 msqid 代表的消息队列发送一个消息即将发送的消息存储在 msgp 指向的 msgbuf 结构中消息的大小由 msgze 指定。 • 参数说明 – 对发送消息来说有意义 的 flag 标志为 IPC_NOWAIT 指明在消息队列没有足够空间容纳要发送的消息时 msgsnd 是否等待。 • 造成 msgsnd () 等待的条件 – 当前消息的大小与当前消息队列中的字节数之和 超过 了消息队列的 总容量 • msgsnd () 解除阻塞的条件有三个 – 消息 队列中有容纳该消息的空间 – msqid 代表的消息队列被删除 – 调用 msgsnd 的进程被信号中断 • 调用返回成功返回 0 否则返回 -1 。 消息队列的基本操作—msgctl()
• 函数原型 – int msgctl (int msqid , int cmd , struct msqid_ds * buf ); • 功能 – 该系统调用对由 msqid 标识的消息队列执行 cmd 操作共有三种 cmd 操作 IPC_STAT 、 IPC_SET 、 IPC_RMID 。 – IPC_STAT 该命令用来获取消息队列信息返回的信息存贮在 buf 指向 的 内存 中 – IPC_SET 该命令用来设置消息队列的属性要设置的属性存储在 buf 指向的 msqid_ds 结构 中可设置属性包括 msg_perm.uid 、 msg_perm.gid 、 msg_perm.mode 以及 msg_qbytes 。 – IPC_RMID 删除 msqid 标识的消息队列 •调用返回成功返回0否则返回-1。
消息队列使用示例——发送
#include stdio.h
#include stdlib.h
#include sys/types.h
#include sys/ipc.h
#include sys/msg.h
#include string.h
struct msg{long msg_types;char msg_buf[512];
};
int main()
{int qid;int pid;int len;struct msg pmsg;pmsg.msg_types getpid();sprintf(pmsg.msg_buf, hello!this is:%d\n,getpid());len strlen(pmsg.msg_buf);//key_t key;//key ftok(“usr/local/test”, 30);if((qid msgget(0x66, IPC_CREAT | 0666))0){perror(msgget);exit(1);}if((msgsnd(qid, pmsg, len, 0))0){perror(msgsnd);exit(1);}printf(successfully send a message to the queue:%d\n, qid);system(ipcs -q);return 0;
}消息队列使用示例——接收
#include stdio.h
#include stdlib.h
#include sys/types.h
#include sys/ipc.h
#include sys/msg.h
#define BUFSIZE 4096
struct msg{long msg_types;char msg_buf[511];
};
int main(int argc, char* argv[])
{int qid, len;struct msg pmsg;qid msgget(0x66,IPC_CREAT | 0666);//key_t key;//key ftok(“usr/local/test”, 30);len msgrcv(qid, pmsg, BUFSIZE, 0, 0);if(len 0){pmsg.msg_buf[len] \0;printf(recving que id:%ld\n,qid);printf(message type:%d\n, pmsg.msg_types);printf(message length:%d\n,len);printf(message text:%s\n,pmsg.msg_buf);}else if(len 0)printf(no message!);else{perror(msgrcv);exit(0);}system(ipcs -q);exit(0);
}