自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Linux中消息隊(duì)列的使用

系統(tǒng) Linux
今天帶小伙伴們學(xué)習(xí)了消息隊(duì)列相關(guān)的內(nèi)容,先簡(jiǎn)單介紹下消息隊(duì)列,然后對(duì)消息隊(duì)列相關(guān)的結(jié)構(gòu)及函數(shù)進(jìn)行學(xué)習(xí),最后擼代碼使用一下這些函數(shù)使用一下消息隊(duì)列,希望對(duì)大家有所幫助哈!

[[386753]]

今天帶小伙伴們學(xué)習(xí)了消息隊(duì)列相關(guān)的內(nèi)容,先簡(jiǎn)單介紹下消息隊(duì)列,然后對(duì)消息隊(duì)列相關(guān)的結(jié)構(gòu)及函數(shù)進(jìn)行學(xué)習(xí),最后擼代碼使用一下這些函數(shù)使用一下消息隊(duì)列,希望對(duì)大家有所幫助哈!

1 消息隊(duì)列的概念及使用過(guò)程

1)消息隊(duì)列的概念

消息隊(duì)列就是一個(gè)消息的鏈表。一條消息可以看作一個(gè)數(shù)據(jù)記錄,此數(shù)據(jù)具有特定的格式。

進(jìn)程可以按照特定的規(guī)則向隊(duì)列中添加(寫(xiě)入)消息;其他的進(jìn)程則可以從消息隊(duì)列中讀走消息。

2)消息隊(duì)列的應(yīng)用場(chǎng)景

消息隊(duì)列本身就是IPC通信中的內(nèi)容,所以它主要用于進(jìn)程間的通信。

消息有讀寫(xiě),所以發(fā)送的消息可以用于動(dòng)作的通知信號(hào),也可以接收數(shù)據(jù)然后做其他處理。

2 消息隊(duì)列相關(guān)的結(jié)構(gòu)及函數(shù)

0)消息隊(duì)列相關(guān)的結(jié)構(gòu)

每個(gè)隊(duì)列都有一個(gè)msqid_ds結(jié)構(gòu)與其相關(guān)聯(lián),結(jié)構(gòu)如下。

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

1)msgget函數(shù)

msgget函數(shù)用于創(chuàng)建或打開(kāi)消息隊(duì)列。

① 函數(shù)原型。

  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>  

③ 參數(shù)。

key:鍵值。

msgflg:打開(kāi)標(biāo)志。IPC_CREAT:表明新創(chuàng)建的一個(gè)消息隊(duì)列。

④ 返回值。

成功:返回消息隊(duì)列的id。

失?。?1。

2)msgsnd函數(shù)

msgsnd函數(shù)用于發(fā)送消息,即寫(xiě)消息到消息隊(duì)列。

① 函數(shù)原型。

  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>  

③ 參數(shù)。

msgid:消息隊(duì)列的id。

msgp:指向要發(fā)送的消息。

msgsz:消息的長(zhǎng)度。

msgflg:標(biāo)志位。

④ 返回值。

成功:0。

失?。?1。

3)msgrcv函數(shù)

msgrcv函數(shù)用于讀消息隊(duì)列,即從消息隊(duì)列接收消息。

① 函數(shù)原型。

  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>  

③ 參數(shù)。

msqid:消息隊(duì)列的id。

msgp:存放消息。

msgsz:希望取到的消息的最大長(zhǎng)度。

msgtyp:消息的類(lèi)型,分下面三種情況:

當(dāng) msgtyp = 0:忽略類(lèi)型,直接取隊(duì)列中的第一條消息。

當(dāng) msgtyp > 0: 取消息隊(duì)列中類(lèi)型等于msgtyp的第一條消息。

當(dāng) msgtyp < 0: 取類(lèi)型比msgtyp的絕對(duì)值要小或等于的消息,如果有多條消息

滿足該條件,取類(lèi)型最小的一條。

④ 返回值。

成功:實(shí)際接收到的消息的數(shù)據(jù)長(zhǎng)度。

失?。?1。

4)msgctl函數(shù)

msgctl函數(shù)用于操作消息隊(duì)列,比如進(jìn)行消息隊(duì)列的刪除等等。

① 函數(shù)原型。

  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>  

③ 參數(shù)。

msqid:消息隊(duì)列的id。

cmd:消息隊(duì)列的操作命令,此參數(shù)指定對(duì)msqid指定的隊(duì)列要執(zhí)行的命令。

IPC_STAT:取此隊(duì)列的msqidds結(jié)構(gòu),并將它存放在buf指向的結(jié)構(gòu)中。

IPCSET:將字段msg_perm.uid、msg_perm.gid、msg_perm.mode和msg_qbytes從buf指向的結(jié)構(gòu)復(fù)制到與這個(gè)隊(duì)列相關(guān)的msqid_ds結(jié)構(gòu)中。

此命令只能由下列兩種進(jìn)程執(zhí)行:

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

另一種是具有超級(jí)用戶特權(quán)的進(jìn)程。只有超級(jí)用戶才能增加msg_qbytes的值。

IPC_RMID:從系統(tǒng)中刪除該消息隊(duì)列以及仍在該隊(duì)列中的所有數(shù)據(jù)。這種刪除立即生效。

仍在使用這一消息隊(duì)列的其他進(jìn)程在它們下一次試圖對(duì)此隊(duì)列進(jìn)行操作時(shí),將得到EIDRM錯(cuò)誤。

此命令只能由下列兩種進(jìn)程執(zhí)行:

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

另一種是具有超級(jí)用戶特權(quán)的進(jìn)程。這3條命令(IPC_STAT、IPC_SET和IPC_RMID)也可用于信號(hào)量和共享存儲(chǔ)。

buf:獲取內(nèi)核中的msqid_ds結(jié)構(gòu),通常不用。

④ 返回值。

成功:0。

失敗:-1。

3 實(shí)例代碼

下面用兩個(gè)進(jìn)程,給大家演示下消息隊(duì)列的使用過(guò)程。

實(shí)例代碼如下,說(shuō)明都在代碼注釋中了,圖片。

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. // 消息結(jié)構(gòu)體 
  8. struct msg 
  9.       long msgtype;       //消息的類(lèi)型 
  10.       char msgtext[1024]; //消息的長(zhǎng)度 
  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.       //創(chuàng)建消息隊(duì)列  
  22.       msgid = msgget(key,0666 | IPC_CREAT); 
  23.  
  24.       //鍵盤(pán)輸入消息 
  25.       while(1) 
  26.       {        
  27.             //獲取消息數(shù)據(jù) 
  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.             //發(fā)送消息 
  40.             msgsnd(msgid,&msgst,sizeof(struct msg),0); 
  41.       } 
  42.  
  43.        //輸出消息隊(duì)列 
  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. // 消息結(jié)構(gòu)體 
  9. struct msg 
  10.       long msgtype; 
  11.       char msgtext[1024]; 
  12. }; 
  13.   
  14.   
  15. int main(int argc, char *argv[]) 
  16.       int RunFlag = 1;                         // 循環(huán)標(biāo)志 
  17.       int msgid = -1;                          // 消息id 
  18.       long msgtp = 0;                          // 消息類(lèi)型 
  19.   
  20.       struct msg msgst;                        // 消息結(jié)構(gòu)體變量 
  21.   
  22.       key_t key = ftok("/tmp",600);            // 創(chuàng)建一個(gè)鍵值 
  23.   
  24.       msgid = msgget(key, 0666 | IPC_CREAT);   //建立消息隊(duì)列 
  25.   
  26.       if(msgid == -1) 
  27.       { 
  28.             exit(1);                           // 異常退出 
  29.       } 
  30.   
  31.   
  32.       while(RunFlag)                           // 從隊(duì)列中獲取消息,直到遇到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結(jié)束 
  42.             { 
  43.                   RunFlag = 0;                // 置退出循環(huán)標(biāo)志 
  44.             } 
  45.     
  46.       } 
  47.   
  48.   
  49.       if(msgctl(msgid, IPC_RMID, 0) == -1)    // 刪除消息隊(duì)列 
  50.       { 
  51.             exit(1);                          // 異常退出 
  52.       } 
  53.         
  54.       exit(0);                                // 正常退出 

編譯程序,先運(yùn)行接收程序,再運(yùn)行發(fā)送程序,輸入要發(fā)送的消息,退出輸入end。

① 兩個(gè)終端運(yùn)行結(jié)果如下:

② 單個(gè)終端運(yùn)行結(jié)果如下:

本文轉(zhuǎn)載自微信公眾號(hào)「嵌入式雜牌軍」,可以通過(guò)以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系嵌入式雜牌軍公眾號(hào)。

 

責(zé)任編輯:武曉燕 來(lái)源: 嵌入式雜牌軍
相關(guān)推薦

2017-06-19 13:36:12

Linux進(jìn)程消息隊(duì)列

2019-05-13 10:00:41

Linux進(jìn)程間通信命令

2024-03-22 12:10:39

Redis消息隊(duì)列數(shù)據(jù)庫(kù)

2022-01-21 19:22:45

RedisList命令

2022-01-15 07:20:18

Redis List 消息隊(duì)列

2017-10-11 15:08:28

消息隊(duì)列常見(jiàn)

2010-01-21 11:23:49

Linux多線程同步消息隊(duì)列

2025-02-26 07:53:21

2024-10-16 15:11:58

消息隊(duì)列系統(tǒng)設(shè)計(jì)

2022-06-28 08:37:07

分布式服務(wù)器WebSocket

2023-11-07 10:01:34

2024-06-05 06:37:19

2010-04-21 14:49:13

Unix消息隊(duì)列

2018-04-26 15:18:49

RTOS應(yīng)用MPU

2024-05-16 08:10:17

RabbitMQ軟件通信機(jī)制

2023-07-26 07:28:55

WebSocket服務(wù)器方案

2020-09-27 07:44:08

RabbitMQ投遞消息

2025-01-02 09:23:05

2023-12-18 08:36:39

消息隊(duì)列微服務(wù)開(kāi)發(fā)

2022-12-13 09:19:26

分布式消息隊(duì)列
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)