Chinaunix首页 | 论坛 | 博客
  • 博客访问: 83067
  • 博文数量: 18
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 85
  • 用 户 组: 普通用户
  • 注册时间: 2014-04-18 09:53
文章分类
文章存档

2015年(18)

我的朋友

分类: LINUX

2015-05-15 17:46:32

消息队列

个人理解消息队列就是以用户定义的type作为数据类型的,一个系统维护的链表,不同进程可以进行读写
涉及到的api如下:
key_t ftok(char *pathname, prj_id)//获取可以值

int msgget(key_t key, int msgflg)//通过key 获取msg的id

int msgctl(int msgqid, int command, struct msgqid_ds *buf)
其中command//仅说明通用的,linux特有的没管
IPC_STAT:获取共享内存的当前信息,存储在buf中
IPC_SET:设置共享内存buf中的 部分信息
IPC_RMID:给共享内存加个标志,在所有进程与共享内存分离后删除之,需要创建该共享内存的成员或者有权限者

ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);//msgtyp表示接受type的类型,为0表示所有的都接收

int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);//注意发送时候 msgp的类型(第一个long变量)必须大于0

void *msgp使用户定义的数据结构,结构如下

struct mymessageStruct {
    long mytypeName; //数据结构类型
    char mydataName[num];//数据内容 num可以是任意大小
};


测试代码如下:

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <sys/msg.h>
  3. #include <sys/ipc.h>
  4. #include <unistd.h>

  5. #define MESSAGE_LEN 100

  6. struct msg_buff//定义消息队列中的一个数据类型的空间
  7. {
  8.     long m_type;
  9.     char m_data[MESSAGE_LEN];
  10. };

  11. int init_message(char *fileName)//初始化消息队列
  12. {
  13.     int msgid;
  14.     key_t key;

  15.     key = ftok(fileName, 1);
  16.     if (key < 0) {
  17.         perror("ftok()");
  18.     }

  19.     msgid = msgget(key, IPC_CREAT | 0600);
  20.     if (msgid < 0) {
  21.         perror("msgget");
  22.     }

  23.     return msgid;
  24. }


  25. int main(int argc, char **argv)
  26. {
  27.     pid_t pid;

  28.     if ((pid = fork()) < 0) {
  29.         perror("fork()");
  30.     } else if (pid == 0) { //child
  31.         int msgid;
  32.         struct msg_buff sb, rb;

  33.         msgid = init_message("/tmp/1");//初始化
  34.         sprintf(sb.m_data, "wwww in child");
  35.         sb.m_type = 1;
  36.         while (1) {
  37.             if (msgsnd(msgid, &sb, MESSAGE_LEN, 0) < 0) {//发送数据
  38.                 perror("msgsnd()");
  39.             }
  40.             if (msgrcv(msgid, &rb, MESSAGE_LEN, 0, 0) < 0) {//接收数据,接收所有数据类型的数据,没有数据会阻塞
  41.                 printf("do not read in child\n");
  42.             } else {
  43.                 printf("child read: %ld, %s\n", rb.m_type, rb.m_data);
  44.             }

  45.             sleep(1);
  46.             sb.m_type++;//换个数据类型,测试下数据类型的影响
  47.         }
  48.     } else { //parent
  49.         int msgid;
  50.         struct msg_buff sb, rb;

  51.         msgid = init_message("/tmp/1");
  52.         sprintf(sb.m_data, "wwww in parent");
  53.         sb.m_type = 1;
  54.         while (1) {
  55.             msgsnd(msgid, &sb, MESSAGE_LEN, 0);
  56.             if (msgrcv(msgid, &rb, MESSAGE_LEN, 1, IPC_NOWAIT) < 0) {//仅接收type为1的数据类型的数据,非阻塞方式接收
  57.                 perror("recv");
  58.             } else {
  59.                 printf("parent read: %ld, %s\n", rb.m_type, rb.m_data);
  60.             }

  61.             sleep(3);
  62.             sb.m_type++;
  63.         }
  64.     }

  65.     return 0;
  66. }


阅读(1481) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~