• 复习 --- 消息队列


    进程间通信机制(IPC)

    简述

    IPC:Inter Process Communication

    进程和进程之间的用户空间相互独立,但是4G内核空间共享,进程间的通信就是通过这4G的内核空间

    分类

    传统的进程间通信机制

    无名管道(pipe)

    有名管道(fifo)

    信号(signal)

    System V中的IPC对象和IPC的区别

    消息队列(message queue)

    共享内存(shared memory)

    信号灯集(semaphore)

    可用于主机传输的通信机制

    套接字(socket)

    消息队列

    概念

    在内核内存中创建一个队列,进程需要将数据打包成结点,添加到队尾中,或者从队列中读取结点,可以通过消息类型进行消息分类

    特点

    需要打包,有特定的格式以及消息类型

    按照先进先出原则,但是也可以限制消息类型读取

    独立于进程,灯进程结束后,消息队列以及其中的内容不会删除,除非中期操作系统或者手动删除

    在Linux系统下,可以通过命令ipcs查看消息队列,通过ipcrm -q msqid删除消息队列

    函数

    ftok()函数,获得一个Key值用来创建消息队列,通过相同的key值可以访问对应的消息队列

    msgget()函数创建一个消息队列获得起id号

    msgsnd()发送消息到指定消息队列

    msgrcv()获取对应消息队列中对应的消息

    msgctl()控制消息队列,常用于删除消息队列

    1. #include
    2. #include
    3. #include
    4. struct msgbuf
    5. {
    6. long mtype; //消息类型
    7. char mtext[128]; //消息内容
    8. };
    9. //线程1函数
    10. void *task1(void *arg)
    11. {
    12. int msqid = *(int *)arg;//获取消息队列id号
    13. struct msgbuf msbuf;//声明消息结构体
    14. printf("A:\n\t");
    15. fflush(stdout);
    16. while (1)
    17. {
    18. msbuf.mtype = 1;//消息类型
    19. fgets(msbuf.mtext,sizeof(msbuf.mtext),stdin);
    20. msbuf.mtext[strlen(msbuf.mtext)-1]='\0';
    21. if(msgsnd(msqid,&msbuf,sizeof(msbuf)-sizeof(long),0) == -1)
    22. {
    23. perror("msgsnd");
    24. return NULL;
    25. }
    26. //printf("线程%d:发送成功\n",getpid());
    27. printf("A:\n\t");
    28. fflush(stdout);
    29. if (!strcmp(msbuf.mtext,"quit"))
    30. {
    31. system("clear");
    32. exit(0);
    33. }
    34. }
    35. pthread_exit(NULL);
    36. }
    37. //线程2函数
    38. void *task2(void *arg)
    39. {
    40. int msqid = *(int *)arg;
    41. struct msgbuf buf;
    42. ssize_t num = 0;
    43. while (1)
    44. {
    45. bzero(&buf,sizeof(buf));
    46. if ((num = msgrcv(msqid,&buf,sizeof(buf.mtext),2,0))<0)
    47. {
    48. //perror("msgrcv");
    49. return NULL;
    50. }
    51. printf("\nB:\n\t%s\n",buf.mtext);
    52. printf("A:\n\t");
    53. fflush(stdout);
    54. if (!strcmp(buf.mtext,"quit"))
    55. {
    56. msgctl(msqid,IPC_RMID,NULL);
    57. system("clear");
    58. exit(0);
    59. }
    60. }
    61. pthread_exit(NULL);
    62. }
    63. int main(int argc, const char *argv[])
    64. {
    65. key_t key = ftok("./",0);
    66. if (key == -1)
    67. {
    68. perror("ftok");
    69. return -1;/* code */
    70. }
    71. umask(0);
    72. int msqid = msgget(key,IPC_CREAT|0664);
    73. if (msqid == -1)
    74. {
    75. perror("msgget");
    76. return -1;
    77. }
    78. pthread_t tid1,tid2;
    79. if (pthread_create(&tid1,NULL,task1,&msqid) != 0)
    80. {
    81. printf("线程1创建失败\n");
    82. }
    83. if (pthread_create(&tid2,NULL,task2,&msqid) != 0)
    84. {
    85. printf("线程1创建失败\n");
    86. }
    87. pthread_join(tid1,NULL);
    88. pthread_join(tid2,NULL);
    89. return 0;
    90. }
    1. #include
    2. //#include
    3. //#include
    4. struct msgbuf
    5. {
    6. long mtype; //消息类型
    7. char mtext[128]; //消息内容
    8. };
    9. //线程1函数
    10. void *task1(void *arg)
    11. {
    12. int msqid = *(int *)arg;
    13. struct msgbuf msbuf;
    14. printf("B:\n\t");
    15. fflush(stdout);
    16. while (1)
    17. {
    18. msbuf.mtype = 2;
    19. fgets(msbuf.mtext,sizeof(msbuf.mtext),stdin);
    20. msbuf.mtext[strlen(msbuf.mtext)-1]='\0';
    21. if(msgsnd(msqid,&msbuf,sizeof(msbuf)-sizeof(long),0) == -1)
    22. {
    23. perror("msgsnd");
    24. return NULL;
    25. }
    26. //printf("线程%d:发送成功\n",getpid());
    27. printf("B:\n\t");
    28. fflush(stdout);
    29. if (!strcmp(msbuf.mtext,"quit"))
    30. {
    31. system("clear");
    32. exit(0);
    33. }
    34. }
    35. pthread_exit(NULL);
    36. }
    37. //线程2函数
    38. void *task2(void *arg)
    39. {
    40. int msqid = *(int *)arg;
    41. struct msgbuf buf;
    42. ssize_t num = 0;
    43. while (1)
    44. {
    45. bzero(&buf,sizeof(buf));
    46. if ((num = msgrcv(msqid,&buf,sizeof(buf.mtext),1,0))<0)
    47. {
    48. //perror("msgrcv");
    49. return NULL;
    50. }
    51. printf("\nA:\n\t%s\n",buf.mtext);
    52. printf("B:\n\t");
    53. fflush(stdout);
    54. if (!strcmp(buf.mtext,"quit"))
    55. {
    56. msgctl(msqid,IPC_RMID,NULL);
    57. system("clear");
    58. exit(0);
    59. }
    60. }
    61. pthread_exit(NULL);
    62. }
    63. int main(int argc, const char *argv[])
    64. {
    65. key_t key = ftok("./",0);
    66. if (key == -1)
    67. {
    68. perror("ftok");
    69. return -1;/* code */
    70. }
    71. umask(0);
    72. int msqid = msgget(key,IPC_CREAT|0664);
    73. if (msqid == -1)
    74. {
    75. perror("msgget");
    76. return -1;
    77. }
    78. pthread_t tid1,tid2;
    79. if (pthread_create(&tid1,NULL,task1,&msqid) != 0)
    80. {
    81. printf("线程1创建失败\n");
    82. }
    83. if (pthread_create(&tid2,NULL,task2,&msqid) != 0)
    84. {
    85. printf("线程1创建失败\n");
    86. }
    87. pthread_join(tid1,NULL);
    88. pthread_join(tid2,NULL);
    89. return 0;
    90. }

  • 相关阅读:
    Motifs与Graphlets
    php-java-net-python-北京名胜古迹展览网站计算机毕业设计程序
    一行配置解决JPA + H2 测试时懒加载LazyInitializationException异常
    find命令
    Error creating bean with name ‘xImpl’: Unsatisfied dependency expressed through field 'baseMapper'
    【无标题】
    数学预备知识
    【力扣练习】找一个字符串中不含有重复字符的最长字串的长度
    Rust 登上了开源头条「GitHub 热点速览」
    【第五篇-完结篇】XiaoZaiMultiAutoAiDevices之改造扩展
  • 原文地址:https://blog.csdn.net/weixin_61882921/article/details/133594163