Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2150617
  • 博文数量: 438
  • 博客积分: 3871
  • 博客等级: 中校
  • 技术积分: 6075
  • 用 户 组: 普通用户
  • 注册时间: 2011-09-10 00:11
个人简介

邮箱: wangcong02345@163.com

文章分类

全部博文(438)

文章存档

2017年(15)

2016年(119)

2015年(91)

2014年(62)

2013年(56)

2012年(79)

2011年(16)

分类: LINUX

2016-02-17 16:34:37

1.


2. mq的send与receive
一个进程调用mq_send发送消息
一个进程调用mq_receive接收消息
mq_send完消息之后,mq_receive可以在任何时间去接收消息
2.1 mq_send
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <fcntl.h> /* For O_* constants */
  5. #include <sys/stat.h> /* For mode constants */
  6. #include <mqueue.h>

  7. #define FILE_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)

  8. int main ( int argc, char *argv[] )
  9. {
  10.     int i;
  11.     int oflag;
  12.     mqd_t mqd;
  13.     struct mq_attr attr;
  14.     char buf[1024];

  15.     oflag = O_CREAT|O_RDWR;
  16.     //mqd_t mq_open(const char *name, int oflag, mode_t mode, struct mq_attr *attr);
  17.     mqd = mq_open("/hellomq", oflag, FILE_MODE, NULL);
  18.     if(mqd < 0)
  19.     {
  20.         perror("mq_open error");
  21.         return -1;
  22.     }
  23.     mq_getattr(mqd, &attr);
  24.     printf("mq_maxmsg=%ld, mq_msgsize=%ld, mq_curmsgs=%ld\n", attr.mq_maxmsg, attr.mq_msgsize, attr.mq_curmsgs);
  25.     for(i=0; i<10; i++)
  26.     {
  27.         snprintf(buf, 10, "mq_send=%d\n", i);
  28.         mq_send(mqd, buf, 10, 3);
  29.     }
  30.     mq_close(mqd);
  31.     return EXIT_SUCCESS;
  32. }
2.2 mq_recv
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <fcntl.h> /* For O_* constants */
  5. #include <sys/stat.h> /* For mode constants */
  6. #include <mqueue.h>

  7. #define FILE_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)

  8. int main ( int argc, char *argv[] )
  9. {
  10.     int i;
  11.     int oflag;
  12.     int prio;
  13.     mqd_t mqd;
  14.     struct mq_attr attr;
  15.     char* buf = NULL;

  16.     oflag = O_CREAT|O_RDWR;
  17.     //mqd_t mq_open(const char *name, int oflag, mode_t mode, struct mq_attr *attr);
  18.     mqd = mq_open("/hellomq", oflag, FILE_MODE, NULL);
  19.     if(mqd < 0)
  20.     {
  21.         perror("mq_open error");
  22.         return -1;
  23.     }
  24.     mq_getattr(mqd, &attr);
  25.     printf("mq_maxmsg=%ld, mq_msgsize=%ld, mq_curmsgs=%ld\n", attr.mq_maxmsg, attr.mq_msgsize, attr.mq_curmsgs);
  26.     //这儿的buf为什么不能预先分配呢?或者用数组呢?
  27.     //因为mq_receive的len参数不能小于mq_msgsize
  28.     //在没有调用mq_getattr之前是不知道mq_msgsiz是多少的,所以需要这儿动态分配
  29.     buf = calloc(attr.mq_msgsize,sizeof(char));
  30.     for(i=0; i<attr.mq_curmsgs; i++)
  31.     {
  32.         mq_receive(mqd, buf, attr.mq_msgsize, &prio);      //注意len参数不能小于能加到所指定队列中的消息的最大大小(mq_msgsize)
  33.         printf("recv:buf=%s,prio=%d\n", buf, prio);
  34.     }
  35.     free(buf);
  36.     mq_close(mqd);
  37.     return EXIT_SUCCESS;
  38. }
3.使用notify
使用步骤:
    a.运行mq_create生成一个mq
   b. 运行mq_receive等侍接收
   c. 运行mq_send发送消息
3.1 加入mq_create
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <fcntl.h> /* For O_* constants */
  5. #include <sys/stat.h> /* For mode constants */
  6. #include <mqueue.h>

  7. #define FILE_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)

  8. int main ( int argc, char *argv[] )
  9. {
  10.     int i;
  11.     int oflag;
  12.     mqd_t mqd;
  13.     struct mq_attr attr;
  14.     char buf[1024];

  15.     oflag = O_CREAT|O_RDWR;
  16.     //mqd_t mq_open(const char *name, int oflag, mode_t mode, struct mq_attr *attr);
  17.     mqd = mq_open("/hellomq", oflag, FILE_MODE, NULL);
  18.     if(mqd < 0)
  19.     {
  20.         perror("mq_open error");
  21.         return -1;
  22.     }
  23.     mq_getattr(mqd, &attr);
  24.     printf("create:mq_maxmsg=%ld, mq_msgsize=%ld, mq_curmsgs=%ld\n", attr.mq_maxmsg, attr.mq_msgsize, attr.mq_curmsgs);
  25.     mq_close(mqd);
  26.     return EXIT_SUCCESS;
  27. }
执行时需要选运行一次mq_create建立mq
3.2 mq_send不变
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <fcntl.h> /* For O_* constants */
  5. #include <sys/stat.h> /* For mode constants */
  6. #include <mqueue.h>

  7. #define FILE_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)

  8. int main ( int argc, char *argv[] )
  9. {
  10.     int i;
  11.     int oflag;
  12.     mqd_t mqd;
  13.     struct mq_attr attr;
  14.     char buf[1024];

  15.     oflag = O_CREAT|O_RDWR;
  16.     //mqd_t mq_open(const char *name, int oflag, mode_t mode, struct mq_attr *attr);
  17.     mqd = mq_open("/hellomq", oflag, FILE_MODE, NULL);
  18.     if(mqd < 0)
  19.     {
  20.         perror("mq_open error");
  21.         return -1;
  22.     }
  23.     mq_getattr(mqd, &attr);
  24.     printf("mq_maxmsg=%ld, mq_msgsize=%ld, mq_curmsgs=%ld\n", attr.mq_maxmsg, attr.mq_msgsize, attr.mq_curmsgs);
  25.     printf("MQ_OPEN_MAX=%ld,MQ_PRIO_MAX=%ld\n", sysconf(_SC_MQ_OPEN_MAX), sysconf(_SC_MQ_PRIO_MAX));
  26.     for(i=0; i<10; i++)
  27.     {
  28.         snprintf(buf, 10, "mq_send=%d\n", i);
  29.         mq_send(mqd, buf, 10, 3);
  30.     }
  31.     mq_close(mqd);
  32.     return EXIT_SUCCESS;
  33. }
3.3 重点mq_receive
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <fcntl.h> /* For O_* constants */
  5. #include <sys/stat.h> /* For mode constants */
  6. #include <mqueue.h>
  7. #include <signal.h>

  8. #define FILE_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)

  9. mqd_t mqd;
  10. struct mq_attr attr;

  11. static void sig_usr1(int signo)
  12. {
  13.     int i;
  14.     int prio;
  15.     char* buf = NULL;
  16.     buf = calloc(attr.mq_msgsize,sizeof(char));
  17.     for(i=0; i<attr.mq_curmsgs; i++)
  18.     {
  19.         mq_receive(mqd, buf, attr.mq_msgsize, &prio);
  20.         printf("recv:buf=%s,prio=%d\n", buf, prio);
  21.     }
  22.     free(buf);
  23. }

  24. int main ( int argc, char *argv[] )
  25. {
  26.     struct sigevent sigev;

  27.     //mqd_t mq_open(const char *name, int oflag, mode_t mode, struct mq_attr *attr);
  28.     mqd = mq_open("/hellomq", O_RDWR, FILE_MODE, NULL);
  29.     if(mqd < 0)
  30.     {
  31.         perror("mq_open error");
  32.         return -1;
  33.     }
  34.     mq_getattr(mqd, &attr);
  35.     printf("mq_maxmsg=%ld, mq_msgsize=%ld, mq_curmsgs=%ld\n", attr.mq_maxmsg, attr.mq_msgsize, attr.mq_curmsgs);
  36.     signal(SIGUSR1, sig_usr1);
  37.     sigev.sigev_notify = SIGEV_SIGNAL;
  38.     sigev.sigev_signo = SIGUSR1;
  39.     mq_notify(mqd, &sigev);
  40.     for(;;)
  41.         pause();
  42.     //mq_close(mqd);
  43.     return EXIT_SUCCESS;
  44. }

3.3.1 改进
a.这儿有个问题: 在运行mq_receive之前,mq不为空,调用mq_recv-->调用mq_send时,
mq_recv不会收到任何singal
  1. cong@msi:/tmp$ man mq_notify
  2. Message notification occurs only when a new message arrives and the queue was previously empty.
  3. 注意:mq_notify产生的条件:队列由空变有数据才会产生一个mq_notify
b.mq_notify只会产生一次信号,
mq_create-->mq_recv-->mq_send 正常,但再次调用mq_send时就不会再产生信号了
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <fcntl.h> /* For O_* constants */
  5. #include <sys/stat.h> /* For mode constants */
  6. #include <mqueue.h>
  7. #include <signal.h>

  8. #define FILE_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)

  9. mqd_t mqd;
  10. struct mq_attr attr;
  11. int read_mq_msg()
  12. {
  13.     int i;
  14.     int prio;
  15.     char* buf = NULL;
  16.     buf = calloc(attr.mq_msgsize,sizeof(char));
  17.     for(i=0; i<attr.mq_curmsgs; i++)
  18.     {
  19.         mq_receive(mqd, buf, attr.mq_msgsize, &prio);
  20.         printf("recv:buf=%s,prio=%d\n", buf, prio);
  21.     }
  22.     free(buf);
  23. }

  24. static void sig_usr1(int signo)
  25. {
  26.     printf("recv signal, and then read\n");
  27.     read_mq_msg();                            //收到signal之后读空队列
  28.     mq_notify_register();                     //并再次等侍接收signal 
  29. }

  30. int mq_notify_register()
  31. {
  32.     struct sigevent sigev;
  33.     signal(SIGUSR1, sig_usr1);
  34.     sigev.sigev_notify = SIGEV_SIGNAL;
  35.     sigev.sigev_signo = SIGUSR1;
  36.     mq_notify(mqd, &sigev);
  37. }

  38. int main ( int argc, char *argv[] )
  39. {
  40.     //mqd_t mq_open(const char *name, int oflag, mode_t mode, struct mq_attr *attr);
  41.     mqd = mq_open("/hellomq", O_RDWR, FILE_MODE, NULL);
  42.     if(mqd < 0)
  43.     {
  44.         perror("mq_open error");
  45.         return -1;
  46.     }
  47.     mq_getattr(mqd, &attr);
  48.     printf("mq_maxmsg=%ld, mq_msgsize=%ld, mq_curmsgs=%ld\n", attr.mq_maxmsg, attr.mq_msgsize, attr.mq_curmsgs);
  49.     if(attr.mq_curmsgs!=0)
  50.     {
  51.         printf("mq_curmsgs is not empty, read it \n");
  52.         read_mq_msg();                 //先把队列中的数据读空
  53.     }
  54.     mq_notify_register();             //产生首次signal
  55.     for(;;)
  56.         pause();
  57.     //mq_close(mqd);
  58.     return EXIT_SUCCESS;
  59. }
4.Makefile
  1. EXE=mq_create mq_send mq_recv
  2. CC=gcc
  3. SRC=$(wildcard *.c)
  4. #OBJ=$(SRC:.c=.o)
  5. OBJ=$(patsubst %.c,%.o,$(SRC))
  6. DEP=$(patsubst %.c,.%.d,$(SRC))
  7. CFLAGS=-g -O0
  8. ALL:$(EXE)
  9. mq_create:mq_create.o
  10.     $(CC) $^ -o $@ -lrt
  11. mq_send:mq_send.o
  12.     $(CC) $^ -o $@ -lrt
  13. mq_recv:mq_recv.o
  14.     $(CC) $^ -o $@ -lrt              ###这儿都要加上-lrt

  15. $(DEP):.%.d:%.c
  16.     @set -e; rm -f $@; \
  17.     $(CC) -MM $< > $@.$$$$; \
  18.     sed 's,/($*/)/.o[ :]*,/1.o $@ : ,g' < $@.$$$$ > $@; \
  19.     rm -f $@.$$$$

  20. -include $(DEP)
  21. clean:
  22.     @rm $(EXE) $(OBJ) $(DEP) *.o -f
5.源码打包 
3mq_notify.rar(下载后改名为3mq_notify.tar.gz)





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

wangcong023452016-05-18 16:54:26

yang305:为什么有错误?

啥错误?把错误发出来看看。

回复 | 举报

yang3052016-05-18 15:56:01

为什么有错误?