成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Linux中消息隊列的使用

系統 Linux
今天帶小伙伴們學習了消息隊列相關的內容,先簡單介紹下消息隊列,然后對消息隊列相關的結構及函數進行學習,最后擼代碼使用一下這些函數使用一下消息隊列,希望對大家有所幫助哈!

[[386753]]

今天帶小伙伴們學習了消息隊列相關的內容,先簡單介紹下消息隊列,然后對消息隊列相關的結構及函數進行學習,最后擼代碼使用一下這些函數使用一下消息隊列,希望對大家有所幫助哈!

1 消息隊列的概念及使用過程

1)消息隊列的概念

消息隊列就是一個消息的鏈表。一條消息可以看作一個數據記錄,此數據具有特定的格式。

進程可以按照特定的規則向隊列中添加(寫入)消息;其他的進程則可以從消息隊列中讀走消息。

2)消息隊列的應用場景

消息隊列本身就是IPC通信中的內容,所以它主要用于進程間的通信。

消息有讀寫,所以發送的消息可以用于動作的通知信號,也可以接收數據然后做其他處理。

2 消息隊列相關的結構及函數

0)消息隊列相關的結構

每個隊列都有一個msqid_ds結構與其相關聯,結構如下。

  1. struct msqid_ds  
  2.      struct ipc_perm msg_perm;     // 消息隊列的存取權限以及其他一些信息                     
  3.      time_t          msg_stime;    // 最近一次隊列接受消息的時間 
  4.      time_t          msg_rtime;    // 最近一次從隊列中取出消息的時間 
  5.      time_t          msg_ctime;    // 最近一次隊列發生改動的時間 
  6.      unsigned long   __msg_cbytes; // 隊列中消息的占用內存的字節數 
  7.      msgqnum_t       msg_qnum;     // 隊列中當前的消息數 
  8.      msglen_t        msg_qbytes;   // 隊列所占用內存的最大字節數 
  9.      pid_t           msg_lspid;    // 最近一次向隊列發送消息的進程的pid msgsnd 
  10.      pid_t           msg_lrpid;    // 最近一次從隊列中取出消息的進程的pid 
  11. }; 
  1. struct ipc_perm 
  2.      key_t key
  3.      ushort uid;         // 用戶id,有效的用戶ID和有效的組id(euid和egid)  
  4.      ushort gid; 
  5.      ushort cuid;        // 創建者的euid和egid  
  6.      ushort cgid; 
  7.      ushort mode;        // 訪問模式參見模式標志  
  8.      ushort seq;         // IPC對象使用頻率信息 
  9. }; 

1)msgget函數

msgget函數用于創建或打開消息隊列。

① 函數原型。

  1. int msgget(key_t key,int msgflg) 

② 頭文件。

  1. include <sys/ipc.h>  
  2.  
  3. include <sys/msg.h>  
  4.  
  5. include <sys/types.h>  

③ 參數。

key:鍵值。

msgflg:打開標志。IPC_CREAT:表明新創建的一個消息隊列。

④ 返回值。

成功:返回消息隊列的id。

失敗:-1。

2)msgsnd函數

msgsnd函數用于發送消息,即寫消息到消息隊列。

① 函數原型。

  1. int msgsnd(int msgid,const void *msgp,size_t msgsz,int msgflg) 

② 頭文件。

  1. include <sys/ipc.h>  
  2.  
  3. include <sys/types.h>  
  4.  
  5. include <sys/msg.h>  

③ 參數。

msgid:消息隊列的id。

msgp:指向要發送的消息。

msgsz:消息的長度。

msgflg:標志位。

④ 返回值。

成功:0。

失敗:-1。

3)msgrcv函數

msgrcv函數用于讀消息隊列,即從消息隊列接收消息。

① 函數原型。

  1. int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg) 
  2.  
  3. ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,intmsgflg) 

② 頭文件。

  1. #include <sys/ipc.h>  
  2.  
  3. #include <sys/types.h> 
  4.  
  5. #include <sys/msg.h>  

③ 參數。

msqid:消息隊列的id。

msgp:存放消息。

msgsz:希望取到的消息的最大長度。

msgtyp:消息的類型,分下面三種情況:

當 msgtyp = 0:忽略類型,直接取隊列中的第一條消息。

當 msgtyp > 0: 取消息隊列中類型等于msgtyp的第一條消息。

當 msgtyp < 0: 取類型比msgtyp的絕對值要小或等于的消息,如果有多條消息

滿足該條件,取類型最小的一條。

④ 返回值。

成功:實際接收到的消息的數據長度。

失敗:-1。

4)msgctl函數

msgctl函數用于操作消息隊列,比如進行消息隊列的刪除等等。

① 函數原型。

  1. int msgctl(int msqid,int cmd,struct msqid_ds *buf) 

② 頭文件。

  1. #include <sys/ipc.h> 
  2.  
  3. #include <sys/msg.h>  
  4.  
  5. #include <sys/types.h>  

③ 參數。

msqid:消息隊列的id。

cmd:消息隊列的操作命令,此參數指定對msqid指定的隊列要執行的命令。

IPC_STAT:取此隊列的msqidds結構,并將它存放在buf指向的結構中。

IPCSET:將字段msg_perm.uid、msg_perm.gid、msg_perm.mode和msg_qbytes從buf指向的結構復制到與這個隊列相關的msqid_ds結構中。

此命令只能由下列兩種進程執行:

一種是其有效用戶ID等于msg_perm.cuid或msg perm.uid。

另一種是具有超級用戶特權的進程。只有超級用戶才能增加msg_qbytes的值。

IPC_RMID:從系統中刪除該消息隊列以及仍在該隊列中的所有數據。這種刪除立即生效。

仍在使用這一消息隊列的其他進程在它們下一次試圖對此隊列進行操作時,將得到EIDRM錯誤。

此命令只能由下列兩種進程執行:

一種是其有效用戶ID等于msg_perm.cuid或msg_perm.uid。

另一種是具有超級用戶特權的進程。這3條命令(IPC_STAT、IPC_SET和IPC_RMID)也可用于信號量和共享存儲。

buf:獲取內核中的msqid_ds結構,通常不用。

④ 返回值。

成功:0。

失敗:-1。

3 實例代碼

下面用兩個進程,給大家演示下消息隊列的使用過程。

實例代碼如下,說明都在代碼注釋中了,圖片。

SendQueue.c。

  1. #include<stdio.h> 
  2. #include<sys/types.h> 
  3. #include<sys/ipc.h> 
  4. #include<sys/msg.h> 
  5. #include<string.h> 
  6.  
  7. // 消息結構體 
  8. struct msg 
  9.       long msgtype;       //消息的類型 
  10.       char msgtext[1024]; //消息的長度 
  11. }; 
  12.  
  13.  
  14. void main(int argc, char *argv[]) 
  15.       int msgid; 
  16.       char str[256]; 
  17.       struct msg msgst; 
  18.    
  19.       key_t key = ftok("/tmp",600); 
  20.  
  21.       //創建消息隊列  
  22.       msgid = msgget(key,0666 | IPC_CREAT); 
  23.  
  24.       //鍵盤輸入消息 
  25.       while(1) 
  26.       {        
  27.             //獲取消息數據 
  28.             printf("\nPlease enter a message to send,input 'end' to quit!\n\n"); 
  29.             scanf("%s",str); 
  30.  
  31.             strcpy(msgst.msgtext,str); 
  32.      
  33.             if(strncmp(str, "end", 3) == 0) 
  34.             { 
  35.                   printf("\n"); 
  36.                   break; 
  37.             } 
  38.  
  39.             //發送消息 
  40.             msgsnd(msgid,&msgst,sizeof(struct msg),0); 
  41.       } 
  42.  
  43.        //輸出消息隊列 
  44.        msgctl(msgid,IPC_RMID,0); 

ReceiveQueue.c。

  1. #include <unistd.h> 
  2. #include <stdlib.h> 
  3. #include <stdio.h> 
  4. #include <string.h> 
  5. #include <errno.h> 
  6. #include <sys/msg.h> 
  7.  
  8. // 消息結構體 
  9. struct msg 
  10.       long msgtype; 
  11.       char msgtext[1024]; 
  12. }; 
  13.   
  14.   
  15. int main(int argc, char *argv[]) 
  16.       int RunFlag = 1;                         // 循環標志 
  17.       int msgid = -1;                          // 消息id 
  18.       long msgtp = 0;                          // 消息類型 
  19.   
  20.       struct msg msgst;                        // 消息結構體變量 
  21.   
  22.       key_t key = ftok("/tmp",600);            // 創建一個鍵值 
  23.   
  24.       msgid = msgget(key, 0666 | IPC_CREAT);   //建立消息隊列 
  25.   
  26.       if(msgid == -1) 
  27.       { 
  28.             exit(1);                           // 異常退出 
  29.       } 
  30.   
  31.   
  32.       while(RunFlag)                           // 從隊列中獲取消息,直到遇到end消息為止 
  33.       { 
  34.             if(msgrcv(msgid,&msgst,sizeof(struct msg), msgtp, 0) == -1) 
  35.             { 
  36.                   exit(1);                     // 異常退出 
  37.             } 
  38.             printf("\nThe message received is: %s\n\n",msgst.msgtext); 
  39.    
  40.    
  41.             if(strncmp(msgst.msgtext, "end", 3) == 0) // 遇到end結束 
  42.             { 
  43.                   RunFlag = 0;                // 置退出循環標志 
  44.             } 
  45.     
  46.       } 
  47.   
  48.   
  49.       if(msgctl(msgid, IPC_RMID, 0) == -1)    // 刪除消息隊列 
  50.       { 
  51.             exit(1);                          // 異常退出 
  52.       } 
  53.         
  54.       exit(0);                                // 正常退出 

編譯程序,先運行接收程序,再運行發送程序,輸入要發送的消息,退出輸入end。

① 兩個終端運行結果如下:

② 單個終端運行結果如下:

本文轉載自微信公眾號「嵌入式雜牌軍」,可以通過以下二維碼關注。轉載本文請聯系嵌入式雜牌軍公眾號。

 

責任編輯:武曉燕 來源: 嵌入式雜牌軍
相關推薦

2017-06-19 13:36:12

Linux進程消息隊列

2019-05-13 10:00:41

Linux進程間通信命令

2024-03-22 12:10:39

Redis消息隊列數據庫

2022-01-15 07:20:18

Redis List 消息隊列

2022-01-21 19:22:45

RedisList命令

2017-10-11 15:08:28

消息隊列常見

2010-01-21 11:23:49

Linux多線程同步消息隊列

2025-02-26 07:53:21

2024-10-16 15:11:58

消息隊列系統設計

2022-06-28 08:37:07

分布式服務器WebSocket

2023-11-07 10:01:34

2010-04-21 14:49:13

Unix消息隊列

2018-04-26 15:18:49

RTOS應用MPU

2024-06-05 06:37:19

2024-05-16 08:10:17

RabbitMQ軟件通信機制

2023-07-26 07:28:55

WebSocket服務器方案

2020-09-27 07:44:08

RabbitMQ投遞消息

2025-01-02 09:23:05

2023-12-18 08:36:39

消息隊列微服務開發

2022-12-13 09:19:26

分布式消息隊列
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 操皮视频| 亚洲精品黄色 | 最近中文字幕免费 | 五月天婷婷狠狠 | 最新中文字幕 | 亚洲精品视频在线观看免费 | 91精品国产乱码久久久久久久久 | 天天操妹子| 丝袜毛片 | 欧美精品video | 色狠狠一区 | 一区二区视频 | 中文字幕在线观看第一页 | 一区2区 | 91pao对白在线播放 | 欧美国产日韩一区 | 91热爆在线观看 | 成年人视频在线免费观看 | 黄色一级片在线播放 | 国产精品免费一区二区三区四区 | 亚洲一区二区三区四区五区中文 | 国产一区二区三区在线视频 | 一级片在线观看 | 91精品国产综合久久小仙女图片 | 亚洲欧洲成人 | 欧美日韩视频 | 亚洲精品www久久久久久广东 | 亚洲狠狠 | 蜜月va乱码一区二区三区 | 不卡一区二区在线观看 | 四虎在线视频 | 国产日韩一区二区 | 欧美综合网 | 天天操天天摸天天干 | 久久国产精品-国产精品 | 亚洲视频免费观看 | 一区在线视频 | 91亚洲一区 | 成人国产精品免费观看视频 | 免费 视频 1级 | 欧美乱码精品一区二区三区 |