================================

msgrcv()函数

============================

msgrcv()函数被用来从消息队列中取出消息。它在linux/msg.h
中的定义是这样的:
系统调用: msgrcv()
函数声明: int msgrcv ( int msqid, struct msgbuf *msgp, int msgsz, long
mtype,
int msgflg )
返回值: Number of bytes copied into message buffer
-1 on error: errno = E2BIG (Message length is greater than
msgsz,
no MSG_NOERROR)
EACCES (No read permission)
EFAULT (Address pointed to by msgp is
invalid)
EIDRM (Queue was removed during
retrieval)
EINTR (Interrupted by arriving signal)
EINVAL (msgqid invalid, or msgsz less than 0)
ENOMSG (IPC_NOWAIT asserted, and no
message
exists in the queue to satisfy the
request)
函数的前三个参数和msgsnd()函数中对应的参数的含义是相同的。第四个参数mtype
指定了函数从队列中所取的消息的类型。函数将从队列中搜索类型与之匹配的消息并将之
返回。不过这里有一个例外。如果mtype 的值是零的话,函数将不做类型检查而自动返回
队列中的最旧的消息。
第五个参数依然是是控制函数行为的标志,取值可以是:
0,表示忽略;
IPC_NOWAIT,如果消息队列为空,则返回一个ENOMSG,并将控制权交回调用函数
的进程。如果不指定这个参数,那么进程将被阻塞直到函数可以从队列中得到符合条件的
消息为止。如果一个client 正在等待消息的时候队列被删除,EIDRM 就会被返回。如果进
程在阻塞等待过程中收到了系统的中断信号,EINTR 就会被返回。
MSG_NOERROR,如果函数取得的消息长度大于msgsz,将只返回msgsz 长度的信息,
剩下的部分被丢弃了。如果不指定这个参数,E2BIG 将被返回,而消息则留在队列中不被
取出。
当消息从队列内取出后,相应的消息就从队列中删除了。
我们将开发一个msgrcv()的封装函数read_message():
int read_message( int qid, long type, struct mymsgbuf *qbuf )
{
int result, length;
/* The length is essentially the size of the structure minus sizeof(mtype) */
length = sizeof(struct mymsgbuf) - sizeof(long);
if((result = msgrcv( qid, qbuf, length, type, 0)) == -1)
{
return(-1);
}
return(result);
}
利用上面提到的msgrcv()对消息长度的处理,我们可以使用下面的方法来检查队列内
是存在符合条件的信息:
int peek_message( int qid, long type )
{
int result, length;
if((result = msgrcv( qid, NULL, 0, type, IPC_NOWAIT)) == -1)
{
if(errno == E2BIG)
return(TRUE);
}
return(FALSE);
}
这里我们将msgp 和msgsz 分别设为NULL 和零。然后检查函数的返回值,如果是E2BIG
则说明存在符合指定类型的消息。一个要注意的地方是IPC_NOWAIT 的使用,它防止了阻塞

=======================

msgsnd()函数

=======================

从函数名就可以看出,msgsnd()函数是用来向消息队列发送消息的。在linux/msg.h 它
的函数定义是这样的:
系统调用: msgsnd()
函数声明: int msgsnd ( int msqid, struct msgbuf *msgp, int msgsz, int msgflg )
返回值: 0 on success
-1 on error: errno = EAGAIN (queue is full, and IPC_NOWAIT was asserted)
EACCES (permission denied, no write permission)
EFAULT (msgp address isn't accessable – invalid)
EIDRM (The message queue has been removed)
EINTR (Received a signal while waiting to write)
EINVAL (Invalid message queue identifier, nonpositive
message type, or invalid message size)
ENOMEM (Not enough memory to copy message buffer)
传给msgsnd()函数的第一个参数msqid 是消息队列对象的标识符(由msgget()函数得
到),第二个参数msgp 指向要发送的消息所在的内存,第三个参数msgsz 是要发送信息的
长度(字节数),可以用以下的公式计算:
msgsz = sizeof(struct mymsgbuf) - sizeof(long);
第四个参数是控制函数行为的标志,可以取以下的值:
0,忽略标志位;
IPC_NOWAIT,如果消息队列已满,消息将不被写入队列,控制权返回调用函数的线
程。如果不指定这个参数,线程将被阻塞直到消息被可以被写入。
这里我们将创建一个封装函数来演示msgsnd()函数的使用:
int send_message( int qid, struct mymsgbuf *qbuf )
{
int result, length;
/* The length is essentially the size of the structure minus sizeof(mtype) */
length = sizeof(struct mymsgbuf) - sizeof(long);
if((result = msgsnd( qid, qbuf, length, 0)) == -1)
{
return(-1);
}
return(result);
}

========================================

msgsnd/msgrcv系统调用

========================================
   
功能描述:
在消息队列上进行收发消息。为了发送消息,调用进程对消息队列必须有写权能。接收消息时必须有读权能。

用法: 
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);

ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);

参数:  
msqid:消息队列的识别码。
msgp:指向消息缓冲区的指针,此位置用来暂时存储发送和接收的消息,是一个用户可定义的通用结构,形态如下

struct msgbuf {
    long mtype;    
    char mtext[1]; 
};

msgsz:消息的大小。
msgtyp:从消息队列内读取的消息形态。如果值为零,则表示消息队列中的所有消息都会被读取。
msgflg:用来指明核心程序在队列没有数据的情况下所应采取的行动。如果msgflg和常数IPC_NOWAIT合用,则在msgsnd()执行时若是消息队列已满,则msgsnd()将不会阻塞,而会立即返回-1,如果执行的是msgrcv(),则在消息队列呈空时,不做等待马上返回-1,并设定错误码为ENOMSG。当msgflg为0时,msgsnd()及msgrcv()在队列呈满或呈空的情形时,采取阻塞等待的处理模式。

返回说明:  
成功执行时,msgsnd()返回0,msgrcv()返回拷贝到mtext数组的实际字节数。失败两者都返回-1,errno被设为以下的某个值
[对于msgsnd] 
EACCES:调用进程在消息队列上没有写权能,同时没有CAP_IPC_OWNER权能
EAGAIN:由于消息队列的msg_qbytes的限制和msgflg中指定IPC_NOWAIT标志,消息不能被发送
EFAULT:msgp指针指向的内存空间不可访问
EIDRM:消息队列已被删除
EINTR:等待消息队列空间可用时被信号中断
EINVAL:参数无效
ENOMEM:系统内存不足,无法将msgp指向的消息拷贝进来
[对于msgrcv]
E2BIG:消息文本长度大于msgsz,并且msgflg中没有指定MSG_NOERROR
EACCES:调用进程没有读权能,同时没具有CAP_IPC_OWNER权能
EAGAIN:消息队列为空,并且msgflg中没有指定IPC_NOWAIT
EFAULT:msgp指向的空间不可访问
EIDRM:当进程睡眠等待接收消息时,消息已被删除
EINTR:当进程睡眠等待接收消息时,被信号中断
EINVAL:参数无效
ENOMSG:msgflg中指定了IPC_NOWAIT,同时所请求类型的消息不存在

msgsnd/msgrcv函数祥解相关推荐

  1. createfile调用失败_CreateFile函数祥解

    CreateFile函数祥解 CreateFile The CreateFile function creates or opens the following objects and returns ...

  2. 函数msgsnd()及函数msgrcv()参数详解

    最近看system V消息队列,在看到msgsnd()这个函数时,发现了一个错误.(注:我看的是UNIX网络编程卷二:进程间通信 第二版) msgsnd()函数:追加一条新消息到消息队列的系统调用语法 ...

  3. (P26)system v消息队列:msgsnd函数 ,msgrcv函数

    文章目录 1.msgsnd函数 2.msgrcv函数 1.msgsnd函数 功能:把一条消息添加到消息队列中原型:int msgsnd(int msqid, const void *msgp, siz ...

  4. msgsnd()函数 msgrcv()函数

    msgsnd()函数 从函数名就可以看出,msgsnd()函数是用来向消息队列发送消息的.在linux/msg.h 它 的函数定义是这样的: 系统调用: msgsnd() 函数声明: int msgs ...

  5. msgsnd函数 msgrcv函数的一些小问题(IPC_NOWAIT慎用!)

    这两个函数别看它简单,真的是一不小心就会出错的啊 报错1:msgsnd: Invalid argument msgrcv: Argument list too long 这真的是一个最常见的错误了.. ...

  6. java邮件附件名称乱码_Javamail 中附件中文名字乱码祥解 (转)

    Javamail 中附件中文名字乱码祥解 (转)[@more@]现在研究JavaMail的人越来越多,现在我就谈谈在javamail中大家都会遇到的附件中文问题,由于sun的java的中文问题,导致当 ...

  7. nginx配置文件祥解

    nginx配置文件祥解 nginx配置说明---------------------------- #运行用户 user  www www; #启动进程 worker_processes  2; #一 ...

  8. msgget();msgsnd();msgrcv();msgctl(); 消息队列 Linux进程间的通信方式之消息队列

    Linux进程间的通信方式 ----消息队列. 消息队列和共享内存类似 消息队列它允许一个或多个进程向它写消息,一个或多个进程向它写读消息. 消息队列存在于系统内核中,消息的数量受系统限制. 我们来看 ...

  9. msgsnd/msgrcv

    消息队列允许长度可变.数目可变的消息排队.任何任务或中断服务程序可以发送消息到消息队列.任何任务可从消息队列接收消息.关于此消息队列的一些常用 函数如下:  int msgget(key_t key, ...

最新文章

  1. PyTorch:MNIST数据集手写数字识别
  2. C#中一些格式的转换
  3. zplane函数怎么用m文件调用_matlab中cla用法
  4. 实现二叉树的基本操作(Java版)
  5. 南阳理工acm 1007GCD
  6. 图片怎么批量修改尺寸
  7. php接入飞鹅打印机
  8. 曹鹏 其言其人 2009-06-15 17:44
  9. 运放自激震荡的大杂烩总结
  10. Python绘图案例实战——用Python画哆啦A梦(超详细步骤分解)
  11. linux jnlp显示异常,使用headless jnlp将slave连接到master时显示异常
  12. DM6467T移植图像算法
  13. 最新高品质+西安市区建筑物范围面shp格式+小区大厦学校医院占地面积
  14. 视频教程-Linux运维高薪课程-Linux
  15. 成功在于实践作文_成功源于行动作文800字
  16. java语言与其他语言的区别是_浅谈Java语言和其他语言的区别
  17. 百度人脸识别API调用(人脸搜索)Java实现
  18. Arduino小项目1---esp8266 WiFi 签到机
  19. yoloV5模型训练教程并进行量化
  20. 中国全轮驱动系统行业市场供需与战略研究报告

热门文章

  1. 信用卡使用时的6点,第六点认真看一下
  2. 导数能不能通过除法 dy/dx 的求出?
  3. ssdb mysql_SSDB高性能NoSQL数据库
  4. 软著申请具体需要哪些步骤呢?
  5. 软件设计师必考精华 - 计算机网络
  6. 腾讯云服务器怎么样?腾讯云服务器性能评测
  7. iText7高级教程之html2pdf——1.从Hello HTML开始
  8. 按占比划分文件,并将文件名写入txt文件
  9. Android png图片彩色转黑白,透明度打印变黑色的解决方法
  10. 树莓派4B+ 连接WIFI后,图标频闪,无法上网