LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 522|回复: 8

消息队列函数的问题

[复制链接]
发表于 2005-2-24 04:52:38 | 显示全部楼层 |阅读模式
程序如下,一个是接受一个发送
这个是发送的
  1. #include<stdlib.h>
  2. #include<stdio.h>
  3. #include<string.h>
  4. #include<unistd.h>
  5. #include<sys/types.h>
  6. #include<sys/ipc.h>
  7. #include<sys/msg.h>
  8. #include"err_exit.h"

  9. struct my_msg{
  10.         long int my_msg_type;
  11.         char text[BUFSIZ];
  12. };
  13. int main()
  14. {
  15.         int running=1;
  16.         struct my_msg msgbuf;
  17.         int msgid;
  18.         msgid=msgget((key_t)1234,0666|IPC_CREAT);
  19.         if(msgid==-1)
  20.                 err_exit("msgget failed\n");
  21.         while(running){
  22.                 printf("enter some text:");
  23.                 fgets(msgbuf.text,BUFSIZ,stdin);
  24.                 msgbuf.my_msg_type=1;
  25.                 if(msgsnd(msgid,(void *)&msgbuf,BUFSIZ,0)==-1)
  26.                         err_exit("msgsend failes\n");
  27.                 if(strncmp(msgbuf.text,"end",3)==0)
  28.                         running=0;
  29.         }
  30.         exit(EXIT_SUCCESS);
  31. }
复制代码
 楼主| 发表于 2005-2-24 04:54:04 | 显示全部楼层
这个是接收的
  1. #include<stdlib.h>
  2. #include<stdio.h>
  3. #include<string.h>
  4. #include<unistd.h>
  5. #include<sys/types.h>
  6. #include<sys/ipc.h>
  7. #include<sys/msg.h>
  8. #include"err_exit.h"

  9. struct my_msg{
  10.         long int my_msg_type;
  11.         char text[BUFSIZ];
  12. };
  13. int main(void)
  14. {
  15.         int running=1;
  16.         int msgid;
  17.         struct my_msg msgbuf;
  18.         long int msg_to_receive=0;
  19.         msgid=msgget((key_t)1234,0666 | IPC_CREAT);
  20.         if(msgid==-1)
  21.                 err_exit("msgget failed\n");
  22.         while(running){
  23.                 if(msgrcv(msgid,(void *)&msgbuf,BUFSIZ,msg_to_receive,0)==-1)
  24.                         err_exit("msgrcv failed\n");
  25.                 printf("you wrote :%s",msgbuf.text);
  26.                 if(strncmp(msgbuf.text,"end",3)==0)
  27.                         running=0;
  28.         }
  29.         if(msgctl(msgid,IPC_RMID,0)==-1)
  30.                 err_exit("msgctl(IPC_RMID) failed\n");
  31.         exit(EXIT_SUCCESS);
  32. }
复制代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-2-24 05:01:27 | 显示全部楼层
程序应该是接收用户输入直到输入“end”,然后发送数据给消息队列,然后接收数据直到“end”,但是我怎么编译通过后输入第三个消息后就不可以输入了。
回复 支持 反对

使用道具 举报

发表于 2005-2-24 10:09:45 | 显示全部楼层
呵呵,我试了一下,没有问题呀。
回复 支持 反对

使用道具 举报

发表于 2005-2-24 20:17:47 | 显示全部楼层
你的第三个消息是不是以end开始呀?把输入贴出来.
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-2-24 20:57:23 | 显示全部楼层
debian:/home# ./p11-14
enter some text:a
enter some text:b
enter some text:c
                                                         /*没有反应了,ctrl+c退出
debian:/home# ./p11-13
you wrote :a
you wrote :b
                                                          /*没有反应了,ctrl+c退出
回复 支持 反对

使用道具 举报

发表于 2005-2-24 21:22:59 | 显示全部楼层
这是我运行的结果
send:

[efan@nktest efan]$ ./snd
enter some text:123
enter some text:333
enter some text:444
enter some text:555
enter some text:a
enter some text:b
enter some text:c
enter some text:end

receive:

[efan@nktest efan]$ ./rcv
you wrote :123
you wrote :333
you wrote :444
you wrote :555
you wrote :a
you wrote :b
you wrote :c
you wrote :end
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-2-25 18:43:18 | 显示全部楼层
语句还有下面的msgsnd:  if(msgrcv(msgid,(void *)&msgbuf,BUFSIZ,msg_to_receive,0)==-1)
                        err_exit("msgrcv failed\n");
中,为什么用BUFSIZ,为什么不是strlen()函数查看出msgbuf的大小!?
函数原型为
int msgrcv(int msgid,const void *msgp,size_t msgsz,int msgflg)
回复 支持 反对

使用道具 举报

发表于 2005-2-26 14:00:20 | 显示全部楼层
找到你的问题了,你的key: 1234生成的msqid是0,用ipcs -q查看, 每次msgrcv后,消息在消息队列里还存在, 用ipcs查看.
输入a之后,
ipcs -q
------ Message Queues --------
key        msqid      owner      perms      used-bytes   messages
0x000004d2 0          jbug       666        8192          1

运行./rcv之后
ipcs -q
------ Message Queues --------
key        msqid      owner      perms      used-bytes   messages
0x000004d2 0          jbug       666        8192          1

从上面的结果可以看出, 消息根本就没有被取出来,可能是由于msqid是0的原因,

系统启动以后,如果第一次用IPC_PRIVATE产生的msqid,也会产生msqid=0的消息队列,我就遇到过好几次,
最好是用文件名产生key,再用key产生msqid,在这种情况下,没有msqid为0的情况,Linux有这个性质,同一个key,比如1234, 假如第一次生成msqid为
key               msqid  
0x000004d2  262144
将它删除后,再产生一次,其msqid的值就变了.
ipcs -q
key        msqid
0x000004d2 458752
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表