• 消息队列实现进程间通信


    发送方代码:

    1. #include
    2. //消息类型结构体
    3. typedef struct{
    4. long msgtype;//消息类型
    5. char data[1024];//消息正文
    6. }Msg_ds;
    7. #define SIZE sizeof(Msg_ds)-sizeof(long)//正文大小
    8. int main(int argc, const char *argv[])
    9. {
    10. //创建key值
    11. key_t key;
    12. if((key=ftok("/",'k'))==-1){
    13. perror("ftok error");
    14. return -1;
    15. }
    16. //创建消息队列
    17. int msgid;
    18. if((msgid=msgget(key,IPC_CREAT|0664))==-1){
    19. perror("msgget error");
    20. return -1;
    21. }
    22. //创建进程
    23. pid_t pid=fork();
    24. if(pid<0){
    25. perror("fork error");
    26. return -1;
    27. }
    28. //子进程
    29. else if(pid==0){
    30. //向消息队列中发送数据
    31. Msg_ds msg1={.msgtype=100};
    32. while(1){
    33. printf("请输入消息内容:");
    34. //从终端输入字符串
    35. fgets(msg1.data,sizeof(msg1.data),stdin);
    36. //将字符串'\n'换成'\0';
    37. msg1.data[strlen(msg1.data)-1]='\0';
    38. //将消息发送到消息队列中
    39. if(msgsnd(msgid,&msg1,SIZE,0)==-1){
    40. perror("msgsnd error");
    41. return -1;
    42. }
    43. if(strcmp(msg1.data,"quit")==0){
    44. break;
    45. }
    46. }
    47. //回收子进程
    48. exit(EXIT_SUCCESS);
    49. }
    50. else{
    51. //从消息队列中取数据
    52. Msg_ds msg;
    53. while(1)
    54. {
    55. //从消息队列中取数据
    56. //第一个0表示取消息的类型,每次都是取第一个
    57. //第二个0表示阻塞方式从消息队列中取数据
    58. if(msgrcv(msgid, &msg, SIZE, 200 ,0) == -1)
    59. {
    60. perror("msgsnd error");
    61. return -1;
    62. }
    63. if(strcmp(msg.data, "quit") == 0)
    64. {
    65. break;
    66. }
    67. printf("rcv: %s\n", msg.data);
    68. }
    69. wait(NULL);
    70. }
    71. msgctl(msgid,IPC_RMID,NULL);
    72. return 0;
    73. }

    接收方代码:

    1. #include
    2. //消息结构体
    3. typedef struct
    4. {
    5. long msgtype; //消息类型
    6. char data[1024]; //消息正文
    7. }Msg_ds;
    8. #define SIZE sizeof(Msg_ds)-sizeof(long) //正文大小
    9. int main(int argc, const char *argv[])
    10. {
    11. //创建key值
    12. key_t key;
    13. if((key = ftok("/", 'k')) == -1)
    14. {
    15. perror("ftok error");
    16. return -1;
    17. }
    18. //2、创建消息队列
    19. int msgid;
    20. if((msgid = msgget(key, IPC_CREAT|0664)) == -1)
    21. {
    22. perror("msgget error");
    23. return -1;
    24. }
    25. pid_t pid=fork();
    26. if(pid<0){
    27. perror("fork error");
    28. return -1;
    29. }
    30. //子进程
    31. else if(pid==0){
    32. //向消息队列中发送数据
    33. Msg_ds msg = {.msgtype = 200};
    34. while(1)
    35. {
    36. printf("请输入消息内容:");
    37. fgets(msg.data, sizeof(msg.data), stdin); //从终端输入字符串
    38. //将字符串的'\n'换成'\0'
    39. msg.data[strlen(msg.data)-1] = '\0';
    40. //将消息发送到消息队列中
    41. if(msgsnd(msgid, &msg, SIZE, 0) == -1)
    42. {
    43. perror("msgsnd error");
    44. return -1;
    45. }
    46. if(strcmp(msg.data, "quit") == 0)
    47. {
    48. break;
    49. }
    50. }
    51. exit(EXIT_SUCCESS);
    52. }
    53. else{
    54. //从消息队列中取数据
    55. Msg_ds msg1;
    56. while(1)
    57. {
    58. //从消息队列中取数据
    59. //第一个0表示取消息的类型,每次都是取第一个
    60. //第二个0表示阻塞方式从消息队列中取数据
    61. if(msgrcv(msgid, &msg1, SIZE, 100 ,0) == -1)
    62. {
    63. perror("msgsnd error");
    64. return -1;
    65. }
    66. if(strcmp(msg1.data, "quit") == 0)
    67. {
    68. break;
    69. }
    70. printf("rcv: %s\n", msg1.data);
    71. }
    72. wait(NULL);
    73. }
    74. msgctl(msgid, IPC_RMID, NULL);
    75. return 0;
    76. }

  • 相关阅读:
    案例突破——再探策略模式
    GIt快速入门(一文学会使用Git)
    (文末赠书)我为什么推荐应该人手一本《人月神话》
    GBase 8s数据库DB-Access全屏菜单界面介绍(3)
    2023年09月青少年软件编程C语言二级真题答案——持续更新.....
    图像中常见变换类型辨析
    R语言ggplot2可视化:使用ggpubr包的ggerrorplot函数可视化误差线(可视化不同水平均值点以及se标准误差)
    Oracle工程师离职并回踩:MySQL糟糕透顶,强烈推荐PostgreSQL
    论文笔记:NeRF++(2020)
    Git常见命令总结
  • 原文地址:https://blog.csdn.net/2301_77665369/article/details/133498489