Linux用消息队列实现父子进程(转)

Linux_父子进程通过消息队列通信


     
     
  1. #include <stdio.h>
  2. #include <wait.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <sys/types.h>
  6. #include <sys/ipc.h>
  7. #include <sys/msg.h>
  8. #include <unistd.h>
  9. #define SIZE 1024
  10. const long id = 1000;//这里规定类型为1000的消息
  11. typedef struct msgqueue{
  12. long mytype;//消息类型
  13. char mytext[SIZE];//消息内容
  14. }msgqueue;
  15. int main(){
  16. key_t k = ftok(".",0x1234);//申请key,确保两个需要通信的进程使用同一个key值获取到的队列id
  17. if(k < 0){
  18. perror("ftok");
  19. return -1;
  20. }
  21. int msgid = msgget(k,IPC_CREAT|IPC_EXCL|0666);//使用key值获取id
  22. if(msgid < 0){
  23. perror("msgget");
  24. return -1;
  25. }
  26. pid_t pid = fork();
  27. if(pid < 0){
  28. perror("fork");
  29. return -1;
  30. }
  31. if(pid > 0){//父进程发消息
  32. msgqueue queue;
  33. queue.mytype = id;//发送的消息类型为1000
  34. char msg[SIZE];
  35. while(1){//循环输入,此时输入的每一条消息,消息类型都是1000
  36. printf("father says# ");
  37. // fflush(stdout);
  38. fgets(msg,sizeof(msg)+1,stdin);//从标准输入获取字符串,以回车换行结束
  39. strcpy(queue.mytext,msg);
  40. if(msgsnd(msgid,&queue,sizeof(msg),0) == -1){//将信息挂载到消息队列里
  41. perror("msgsnd");
  42. return -1;
  43. }
  44. if(strncmp(msg,"end",3) == 0){//只要输入end,认为结束通信
  45. break;
  46. }
  47. usleep(500000);
  48. }
  49. waitpid(pid,NULL,0);//等待子进程退出
  50. }else if(pid == 0){//子进程取消息,注意消息队列里只要有人拿了消息,那么拿走的消息就不在消息队列里了
  51. msgqueue queue;
  52. while(1){//循环拿消息
  53. if(msgrcv(msgid,&queue,sizeof(queue.mytext),id,0) == -1){//从消息队列里取消息,取一个少一个
  54. perror("msgrcv");
  55. return -1;
  56. }
  57. if(strncmp(queue.mytext,"end",3)==0){//end就退出
  58. printf("father will quit,i quit too\n");
  59. break;
  60. }
  61. printf("child recv:%s\n",queue.mytext);
  62. }
  63. exit(EXIT_SUCCESS);
  64. }
  65. if(msgctl(msgid,IPC_RMID,NULL) <0){//删除消息队列,因为消息队列创建后不会自己删除,必须人为删除或者重启
  66. perror("msgctl");
  67. return -1;
  68. }
  69. printf("\n done \n");//没什么含义,只是为了表示这次的传输是正常退出的
  70. return 0;
  71. }

  •                     <li class="tool-item tool-active is-like "><a href="javascript:;"><svg class="icon" aria-hidden="true">
                            <use xlink:href="#csdnc-thumbsup"></use>
                        </svg><span class="name">点赞</span>
                        <span class="count"></span>
                        </a></li>
                        <li class="tool-item tool-active is-collection "><a href="javascript:;" data-report-click="{&quot;mod&quot;:&quot;popu_824&quot;}"><svg class="icon" aria-hidden="true">
                            <use xlink:href="#icon-csdnc-Collection-G"></use>
                        </svg><span class="name">收藏</span></a></li>
                        <li class="tool-item tool-active is-share"><a href="javascript:;" data-report-click="{&quot;mod&quot;:&quot;1582594662_002&quot;}"><svg class="icon" aria-hidden="true">
                            <use xlink:href="#icon-csdnc-fenxiang"></use>
                        </svg>分享</a></li>
                        <!--打赏开始-->
                                                <!--打赏结束-->
                                                <li class="tool-item tool-more">
                            <a>
                            <svg t="1575545411852" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5717" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M179.176 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5718"></path><path d="M509.684 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5719"></path><path d="M846.175 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5720"></path></svg>
                            </a>
                            <ul class="more-box">
                                <li class="item"><a class="article-report">文章举报</a></li>
                            </ul>
                        </li>
                                            </ul>
                </div>
                            </div>
            <div class="person-messagebox">
                <div class="left-message"><a href="https://blog.csdn.net/qq_40425540">
                    <img src="https://profile.csdnimg.cn/2/A/2/3_qq_40425540" class="avatar_pic" username="qq_40425540">
                                            <img src="https://g.csdnimg.cn/static/user-reg-year/2x/3.png" class="user-years">
                                    </a></div>
                <div class="middle-message">
                                        <div class="title"><span class="tit"><a href="https://blog.csdn.net/qq_40425540" data-report-click="{&quot;mod&quot;:&quot;popu_379&quot;}" target="_blank">s1f</a></span>
                                            </div>
                    <div class="text"><span>发布了29 篇原创文章</span> · <span>获赞 7</span> · <span>访问量 8463</span></div>
                </div>
                                <div class="right-message">
                                            <a href="https://im.csdn.net/im/main.html?userName=qq_40425540" target="_blank" class="btn btn-sm btn-red-hollow bt-button personal-letter">私信
                        </a>
                                                            <a class="btn btn-sm  bt-button personal-watch" data-report-click="{&quot;mod&quot;:&quot;popu_379&quot;}">关注</a>
                                    </div>
                            </div>
                    </div>
    </article>
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
进程代码: ```c #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #define MSG_KEY 1234 struct msgbuf { long mtype; int mtext; }; int main() { int i; int sum = 0; struct msgbuf msg; // 创建消息队列 int msgid = msgget(MSG_KEY, IPC_CREAT | 0666); if (msgid == -1) { perror("msgget failed"); exit(EXIT_FAILURE); } // 发送消息子进程 for (i = 1; i <= 10; i++) { msg.mtype = 1; msg.mtext = i; if (msgsnd(msgid, &msg, sizeof(msg.mtext), 0) == -1) { perror("msgsnd failed"); exit(EXIT_FAILURE); } } // 接收子进程发送消息 if (msgrcv(msgid, &msg, sizeof(msg.mtext), 2, 0) == -1) { perror("msgrcv failed"); exit(EXIT_FAILURE); } sum = msg.mtext; printf("Sum is %d\n", sum); // 删除消息队列 if (msgctl(msgid, IPC_RMID, NULL) == -1) { perror("msgctl failed"); exit(EXIT_FAILURE); } return 0; } ``` 子进程代码: ```c #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #define MSG_KEY 1234 struct msgbuf { long mtype; int mtext; }; int main() { int i; int sum = 0; struct msgbuf msg; // 创建消息队列 int msgid = msgget(MSG_KEY, 0666); if (msgid == -1) { perror("msgget failed"); exit(EXIT_FAILURE); } // 接收进程发送消息 for (i = 1; i <= 10; i++) { if (msgrcv(msgid, &msg, sizeof(msg.mtext), 1, 0) == -1) { perror("msgrcv failed"); exit(EXIT_FAILURE); } sum += msg.mtext; } // 发送总和给进程 msg.mtype = 2; msg.mtext = sum; if (msgsnd(msgid, &msg, sizeof(msg.mtext), 0) == -1) { perror("msgsnd failed"); exit(EXIT_FAILURE); } return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值