• 系统编程 day12 (linux ) 消息队列 的函数 与知识


    1.消息队列是啥?

    消息队列就是一个消息的链表。就是把消息看作一个记录,并且这个记录具有特定的格式以及特定的优先级。对消息队列有写权限的进程可以按照一定的规则添加新消息;对消息队列有读权限的进程则可以从消息队列中读出消息。


    2.消息队列的特点:

    1.发送方不必等待接收方检查它所收到的消息就可以继续工作下去,而接收方如果没有收到消息也不需等待(异步)。

    2.新的消息总是放在队列的末尾,接收的时候并不总是从头来接收,可以从中间来接收。

    3.消息队列随内核和进程相关,只有在内核重启或者显式删除一个消息队列时,该消息队列才会真正被删除。


    3.消息队列的使用步骤:(函数的使用)

    (1)msgget:得到一个消息队列,当这个消息队列存在的时候, 这个消息调用负责返回这个队列的标识号;如果这个队列不存在,就创建一个消息队列,然后返回这个消息队列的标识号 (2)msgsnd:向一个消息队列发送一个消息

    (3)msgrcv:从一个消息队列中收到一个消息

    (4)msgctl:在消息队列上执行指定的操作。根据参数的不同和权限的不同,可以执行检索、删除等的操作


    4.函数的原型  参数  功能  返回值 

    msgget--得到一个消息队列

    头文件:#include

    #include

    #include

    函数原型:int msgget (key_t key, int msgflg);

    参数:key 为由 ftok 创建的 key 值,msgflg 的低位用来确定消息队列的访问权限,如 0770。还可以附加以下参数值: IPC_CREAT 00001000//如果 key不存在,创建 IPC_EXCL 00002000//如果 key 存在,返回失败 IPC_NOWAIT 00004000 //如果需要等待,直接返回错误

    返回值:成功返回IPC标识符,不成功返回-1


    5.msgsnd()--发送信息到消息队列

    头文件:sys/msg.h

    原型: int msgsnd (int msqid, const void *msgp, size_t msgsz, int msgflg);

    参数:msqid 为指定的消息队列标识符 msgp 为指向的用户定义缓冲区,

    其结构如下:

    struct msgbuf {   

     long mtype; //消息类型   

     char mtext[512]; //消息内容,使用时自己重新定义此结构

                            };

    msgsz为发送信息的大小,其大小为 0到系统对消息队列的限制值。

    msgflg用来指定在达到系统为消息队列所定的界限时应采取的操作。 可为以下值:  IPC_NOWAIT:若消息队列已满(或者是队列中的消息总数等于系统限制值,或队列中的字节总数等于系统限制值),则指定IPC_NOWAIT使得msgsnd立即出错返回EAGAIN。如果没有指定IPC_NOWAIT ,则进程阻塞直到有空间可以容纳要发送的消息,或从系统中删除了此队列在成功调用后,将对消息队列 msqid 数据结构的成员执行下列操作:     msg_qnum 以 1 为增量递增。     msg_lspid 设置为调用进程的进程 ID。     msg_stime 设置为当前时间。

    返回值:成功返回0,失败返回-1


    5.msgrcv--接收消息队列

    头文件:sys/msg.h

    原型:int msgrcv(int msqid,struct msgbuf *msgp,size_t msgsz,long int msgtyp,int msgflg);

    参数:msqid:消息队列描述符。  

     msgp:读取的消息存储到msgp指向的消息结构中。  

     msgsz:消息缓冲区的大小。  

     msgtyp:为请求读取的消息类型。  

     msgflg:操作标志位。

    msgflg可以为IPC_NOWAIT,IPC_EXCEPT,IPC_NOERROR: IPC_NOWAIT:如果没有满足条件的消息,调用立即返回 IPC_EXCEPT:与msgtyp配合使用,返回队列中第一个类型不为msgtyp的消息; IPC_NOERROR:如果队列中满足条件的消息内容大于所请求的msgsz字节,则把该消息截断,截断部分将被丢弃。

    返回值:成功会返回消息的实际字节数,否则返回-1


    6.msgctl--消息队列属性控制

    头文件: #include

    #include

    #include

    原型:int msgctl (int msqid, int cmd, struct msqid_ds *buf)

    参数:

    msqid 为消息队列标识符,

    cmd 为执行的控制命令,可为:     IPC_STAT:读取消息队列属性。     IPC_SET :设置消息队列属性。     IPC_RMID:删除消息队列。     IPC_INFO:读取消息队列基本情况 buf为msqid_ds 结构体类型的变量。用于存储读取的消息队列属性或者需要修改的消息队列属性

    返回值:成功返回0,不成功返回-1


    代码: (代码 有bug    那个 无用的字符数组 不要删   没有它,不能执行 )

    1. /************************************************************************************************************************************************************************************************************************
    2. *文件名:
    3. *作 者:She001
    4. *时 间:
    5. *版 本:
    6. *作 用:消息队列
    7. ****************************************************************************************************************************************************************************************************************************/
    8. #include
    9. #include
    10. #include
    11. #include
    12. #include
    13. #include
    14. #include
    15. #include
    16. #include
    17. #include
    18. #include
    19. #include
    20. #include
    21. #include
    22. #include
    23. #include
    24. #include
    25. #include
    26. #include
    27. #include
    28. #include
    29. #include
    30. #include
    31. #include
    32. #include
    33. #include
    34. #include
    35. #include
    36. #include
    37. //ipcs -q 查看命令
    38. //1.消息队列功能的使用测试
    39. //2.创建一个消息队列
    40. //2.向消息队列中写入数据
    41. //3.从消息队列中读取数据
    42. //销毁消息队列
    43. struct msgbuf
    44. {
    45. long msgtype; //8个字节
    46. char msgtext[512]; //字符串内容
    47. };
    48. int main()
    49. {
    50. //获取一个键值
    51. key_t key = ftok(".",50);
    52. if(key < 0)
    53. {
    54. perror("ftok error\n");
    55. return -1;
    56. }
    57. printf("ftok is ok\n");
    58. printf("key is : %d\n",key);
    59. //获取一个消息队列
    60. int msgid = msgget(key,IPC_CREAT | 0666);
    61. if(msgid < 0)
    62. {
    63. perror("msgget is error\n");
    64. return -1;
    65. }
    66. printf("msgid is : %d\n",msgid);
    67. //向消息队列中添数据
    68. struct msgbuf msgstr = {1,"hello linux"};
    69. char *str = "hello linux";
    70. int msgerr = msgsnd(msgid,&msgstr,sizeof(msgstr),IPC_NOWAIT);
    71. if(msgerr <0)
    72. {
    73. perror("msgsnd error\n");
    74. return -1;
    75. }
    76. struct msgbuf msgstr1 = {0};
    77. char buff[128] = "";
    78. int msglen = msgrcv(msgid,&msgstr1,sizeof(msgstr1),1,0);
    79. printf("msgbuf is :%s msgtype is : %ld %d\n",msgstr1.msgtext,msgstr1.msgtype,msglen);
    80. //删除消息队列
    81. msgctl(msgid,IPC_RMID,NULL);
    82. return 0 ;
    83. }

  • 相关阅读:
    golang之slice并发访问
    考CISAW的N个理由!
    计算机毕业设计Java校园兼职招聘系统(源码+系统+mysql数据库+Lw文档)
    JSTL 标签库
    44LVS负载均衡群集-NAT
    SHELL编程基础2
    邮箱被攻击,后悔没有早早的做好安全措施
    ucos任务调度原理
    2022年广西壮族自治区中职网络安全技能竞赛“Linux操作系统渗透测试详解”
    python模块之aioHttp 异步请求
  • 原文地址:https://blog.csdn.net/she666666/article/details/126274475