【网络编程】多进程编程--消息队列

文章目录

  • 一、msgget系统调用
  • 二、msgsnd系统调用
  • 三、msgrcv系统调用
  • 四、msgctl系统调用


一、msgget系统调用

  msgget系统调用创建一个消息队列,或者获取一个已有的消息队列,定义如下:

#include 
int msgget(key_t key, int msgflg);
  • key是一个键值,用来标识一个全局唯一的消息队列。
  • msgflg参数和含义与semget系统调用的sem_flag参数相同。

  msgget成功时返回一个正整数,它是消息队列的标识符,msgget失败时返回-1并设置errno。
  使用msgget创建消息队列,则与之相关的内核数据结构也会被创建兵器初始化。其定义如下:

struct msqid_ds{
	struct ipc_perm msg_perm;  /*消息队列的操作权限*/
	time_t msg_stime;          /*最后一次调用msgsnd的时间*/
	time_t msg_rtime;          /*最后一次调用msgrcv的时间*/
	time_t msg_ctime;          /*最后一次被修改的时间*/
	unsigned long __msg_cbytes;/*消息队列中已有的字节数*/
	msgqnum_t msg_qnum;        /*消息队列中已有的消息数*/
	msglen_t msg_qbytes;       /*消息队列允许的最大字节数*/
	pid_t msg_lspid;           /*最后执行msgsnd的进程PID*/
	pid_t msg_lrpid;           /*最后执行msgrcv的进程PID*/
};

二、msgsnd系统调用

  msgsnd系统调用将一条消息添加到消息队列中,定义如下:

#include 
int msgsnd(int msqid, const void* msg_ptr, size_t msg_sz, int msgflg);
  • msqid是由msgget调用返回的消息队列标识符。
  • msgflg控制msgsnd的行为,它通常仅支持IPC_NOWAIT标志,以非阻塞方式发送消息。但是如果消息队列满了,则msgsnd阻塞。若IPC_NOWAIT标志被指定,msgsnd立即返回并设置errno为EAGAIN。
  • msg_ptr指向一个即将发送的消息,其定义必须如下:
struct msgbuf{
	long mtype;      /*消息类型*/
	char mtext[512]; /*消息数据*/
};

  处于阻塞状态的msgsnd调用可能被以下两种异常情况所中断:

  • 消息队列被移除。此时msgsnd调用将立即返回并设置errno为EIDRM。
  • 程序接收到信号,此时msgsnd调用将立即返回并设置errno为EINRT。

  msgsnd成功时返回0,失败是返回-1并设置errno。msgsnd成功时将修改内核数据结构msqid_ds的部分字段,如下所示:

  • 将msg_qnum加1。
  • 将msg_lspid设置为调用进程的PID。
  • 将msg_stime设置为当前的时间。

三、msgrcv系统调用

  msgrcv系统调用从消息队列中获取消息。其定义为:

#include 
int msgrcv(int msqid, void* msg_ptr, size_t msg_sz, long int msqtype, int msgflg);
  • msqid是由msgget调用返回的消息队列标识符。
  • msg_ptr用于存储接收的消息,msg_sz是消息数据部分的长度。
  • msgtype指定接收何种类型的数据,由以下几个方式:
    • msgtype等于0。读取消息队列中的第一个消息。
    • msgtype大于0。读取消息队列中第一个类型为msgtype的消息。
    • msgtype小于0。读取消息队列中第一个类型值比msgtype的绝对值小的消息。

  msgflg控制msgrcv函数的行为,它可以是以下一些标志的按位或:

  • IPC_NOWAIT,如果消息队列中没有消息,则msgrcv调用立即返回并设置errno为ENOMSG。
  • MSG_EXCEPT,如果msgtype大于0,则接收消息队列中第一个非msgtype类型的消息。
  • MSG_NOERROR,如果消息数据部分的长度超过了msg_sz,就将它截断。

  处于阻塞状态的msgrcv调用还可能被以下两种异常情况中断:

  • 消息队列被移除。此时msgrcv调用将立即返回并设置errno为EIDRM。
  • 程序接收到信号。此时msgrcv调用 将立即返回并设置errno为EINTR。

  msgrcv成功时返回0,失败则返回-1并设置errno。msgrcv成功时修改内核数据结构msqid_ds的部分字段如下:

  • 将msg_qnum减1;
  • 将msg_lrpid设置为调用进程的PID;
  • 将msg_rtime设置为当前时间。

四、msgctl系统调用

  msgctl系统调用控制消息队列的属性。

#include 
int msgctl(int msqid, int command, struct msqid_ds* buf);
  • msqid是由msgget调用返回的共享内存标识符。
  • command是要执行的命令,msgctl支持的命令在P265。

  msgctl成功时的返回值取决于command参数,失败时返回-1并设置errno。


《Linux高性能服务器编程》学习笔记

你可能感兴趣的:(网络编程,linux)