IPC - Linux 消息队列函数及应用欣赏一

来源:互联网 发布:sql数据库大小限制 编辑:程序博客网 时间:2024/04/29 04:07


--------------------------------------

应用实例

--------------------------------------

<span style="font-size:14px;">/* 创建消息队列msqid,终端输入字符串(<256bytes),存于msg0结构中,发送msg0消息到消息队列msqid, 然后再从此消息队列读出消息存于msg1结构中并输出。有重复了一次这个操作,只是这次用的字符串常量来填充msg0.  此消息队列通过IPC_RMID删除,具体测试时大家可以用 ipcs -q 来查看,同时echo $?可以查看main函数返回值*/</span>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/msg.h>#define __DEBUG/* Enables or disables debug output */#ifdef __DEBUG#define DBG(fmt, args...) fprintf(stderr, "XJTU_DBG: " fmt, ## args)#else#define DBG(fmt, args...)#endif#define ERR(fmt, args...) fprintf(stderr, "XJTU_ERR: " fmt, ## args)struct msg_struct {/* begin with long int type */long int msg_type;/* the data type you wish to transfer */char msg_text[256];};int main(int argc,char *argv[]){struct msg_struct msg0,msg1;int msqid;int len  = 0;char *src = "Welcome to xi'an! Email: sinonion.ma@gmail.com";/* 0666:not a device file,u+g+o w+r */if((msqid = msgget((key_t)1234, 0666|IPC_CREAT)) == -1){ERR("msgget error!\n");exit(1);}DBG("msqID=%i\n",msqid);/* Waiting to receive a string from terminal */if(fgets((&msg0)->msg_text, 200, stdin) == NULL){ERR("no message input!\n");exit(2);}/* Generally, msg_type = getpid() */msg0.msg_type = getpid();len = strlen(msg0.msg_text);if(msgsnd(msqid, &msg0, len, 0) < 0){ERR("msgsnd error!\n");exit(3);}if(msgrcv(msqid, &msg1, 200, 0, 0) < 0){ERR("msgrcv error!\n");exit(4);}DBG("recv message is %s\n",msg1.msg_text);len = strlen(src);memset(msg0.msg_text,0,sizeof(msg0.msg_text));memcpy(msg0.msg_text,src,len);if(msgsnd(msqid, &msg0, len, 0) < 0){ERR("msgsnd error!\n");exit(3);}if(msgrcv(msqid, &msg1, 200, 0, 0) < 0){ERR("msgrcv error!\n");exit(4);}DBG("recv message is %s\n",msg1.msg_text);#if 1if(msgctl(msqid, IPC_RMID, NULL) < 0){ERR("del msq error!\n");exit(5);}#endifexit(0);}

--------------------------------------

代码测试

--------------------------------------

系统

调用

函数

原型

#include <sys/msg.h>

/* 创建或打开一个消息队列 */

int msgget(key_t key, int msgflg);

/* msqid打开的消息队列发一个消息进去 */

int msgsnd(int msqid, struct msgbuf *msg_ptr, size_t msg_sz, int msgflg);

/* msqid打开的消息队列读取一个消息放在msg_ptr中 */

int msgrcv(int msqid, struct msgbuf *msg_ptr, size_t msg_sz, long int msgtype, int msgflg);

/* msqid打开的消息队列执行cmd操作 */

int msgctl(int msqid, int cmd, struct msqid_ds *buf);

消息

基本

结构

Struct msgbuf{

  long int msg_type;

  /* the data you wish to transfer */

  char msg_text[256];

}

msg_type用于接收消息,此值代表消息类型,不能简单忽略,并且消息必须以long int类型开始。

输入

参数

key_t key系统建立IPC通讯(如消息队列、共享内存时)必须指定一个ID值,一般由ftok函数创建(改天专门说此问题)

int msgflgt两部分组成,新消息权限 消息操作组成(参见例子)

struct msgbuf *msg_ptr:指向消息结构体的指针(参看例子)

对于发送函数,事先要将发送内容写入消息结构体;

对于接受函数,事先要创建好消息结构体,准备接收。

size_t msg_sz:指向结构体中消息内容的长度

int msqid:消息队列ID,由msgget返回值确定

int cmd: 三种操作

IPC_STAT,:获取消息队列信息,存贮在struct msqid_ds *buf

IPC_SET:设置消息队列属性,要设置的属性存贮在struct msqid_ds *buf

IPC_RMID:删除msqid标示的消息队列

 

 

输出

参数

int msgget(key_t key, int msgflg);

调用成功返回消息队列ID,否则返回-1

int msgsnd(int msqid, struct msgbuf *msg_ptr, size_t msg_sz, int msgflg);

调用成功返回0,失败返回-1

int msgrcv

(int msqid, struct msgbuf *msg_ptr, size_t msg_sz, long int msgtype, int msgflg);

调用成功返回读出的消息实际字节数,失败返回-1

int msgctl(int msqid, int cmd, struct msqid_ds *buf);

调用成功返回0,失败-1

 

--------------------------------------

简介

--------------------------------------

消息队列实现两个不相关进程间不同类型数据块的传递,其优势在于既不依赖发送进程,也不依赖接收进程,它们可以独立存在,少掉了像命名管道那样打开和关闭时必须同步和协调。

消息队列看成一个消息链表,其实现包括4种操作:创建或打开已有消息队列、添加消息队列、读取消息队列、控制消息队列。进程对已打开或创建的消息队列进行操作还必须有相应的权限。


0 0