国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Linux > 正文

Linux下消息隊列學習筆記

2024-08-27 23:59:10
字體:
來源:轉載
供稿:網友

消息隊列是進程間通訊的一種方法,一開始我以為消息隊列是類似一個管道,一頭連接一個進程、一頭連接另一個進程,只能由這兩個進程來進行互相的讀寫,其實這是錯的,消息隊列是系統層面的,它不屬于某兩個進程,它是由系統維護的一個鏈表結構,對消息隊列的讀寫就是一個對鏈表的操作,默認是在鏈表的一端寫數據,另一端讀數據(先進先出),進程也可以取指定某種消息類型的消息.

在一個進程里創建了消息隊列,且是可讀可寫的,那么系統中的所有進程都可以對它進行讀寫操作.

1、打開或創建一個消息隊列

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

參數:

1)key:消息隊列的key值。

2)msgflg:

IPC_CREAT:如果key對應的消息隊列對象不存在,則創建,否則則進行打開操作,返回0.

IPC_EXCL:如果key對應的消息隊列對象不存在,則返回-1;否則則進行打開操作,返回0。

權限控制:0666表示可讀可寫,和上面的IPC_CREAT做邏輯或操作.

返回值:成功返回,創建的或打開的消息隊列的id,失敗返回-1.

例子程序:test1.c,代碼如下:

  1. #include <sys/types.h> 
  2. #include <sys/ipc.h> 
  3. #include <sys/msg.h> 
  4. #include <stdio.h> 
  5. int main(void) 
  6.  int msgid; 
  7.  printf("this is test1!\n"); 
  8.  
  9.  msgid = msgget(1001, 0666|IPC_CREAT); 
  10.  printf("msgid = %d\n", msgid); 
  11.  
  12.  return 0; 

執行結果:

  1. [root@server ~]# gcc -o test1 test1.c 
  2. [root@server ~]# ./test1 
  3. this is test1! 
  4. msgid = 32768 
  5. [root@server ~]# ipcs 
  6. ------ Shared Memory Segments -------- 
  7. key        shmid      owner      perms      bytes      nattch     status      
  8. ------ Semaphore Arrays -------- 
  9. key        semid      owner      perms      nsems      
  10. 0x00000000 0          root       600        1         
  11. ------ Message Queues --------  //Vevb.com 
  12. key        msqid      owner      perms      used-bytes   messages     
  13. 0x000003e9 32768      root       666        0            0      

從ipcs命令的結果可以知道,消息隊列在創建它的進程退出后,還存在于系統中,說明消息隊列是系統一層的,并不是屬于某個進程的.

2、設置消息隊列屬性(包括刪除)

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

參數:

1)msqid:消息隊列的id.

2)cmd:執行的控制命令.

IPC_STAT:讀取消息隊列屬性,取得此隊列的msqid_ds 結構,并將其存放在buf指向的結構中.

IPC_SET:設置消息隊列屬性.

IPC_RMID:刪除消息隊列.

IPC_INFO:讀取消息隊列基本情況,此命令等同于 ipcs 命令.

例子程序:test2.c,代碼如下:

  1. #include <sys/types.h> 
  2. #include <sys/ipc.h> 
  3. #include <sys/msg.h> 
  4. #include <stdio.h> 
  5. int main(void) 
  6.  int i; 
  7.  printf("this is test2!\n"); 
  8.  i = msgctl(32768, IPC_RMID, NULL);//這里已經知道消息id等于32768 
  9.  if (0 == i) 
  10.  { 
  11.   printf("msq deleted!\n"); 
  12.  } 
  13.  return 0; 
  14. //執行結果: 
  15. [root@server ~]# gcc -o test2 test2.c 
  16. [root@server ~]# ./test2 
  17. this is test2! 
  18. msq deleted! 
  19. [root@server ~]# ipcs 
  20. ------ Shared Memory Segments -------- 
  21. key        shmid      owner      perms      bytes      nattch     status      
  22. ------ Semaphore Arrays -------- 
  23. key        semid      owner      perms      nsems      
  24. 0x00000000 0          root       600        1         
  25. ------ Message Queues -------- 
  26. key        msqid      owner      perms      used-bytes   messages 

原有的消息隊列被刪除了.

3、向消息隊列寫/讀消息

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

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

參數:

1)msqid:消息隊列的id.

2)msgp:指向消息緩沖區的指針,該指針指向如下的一個用戶可定義的通用結構.

  1. struct mymsg { 
  2.   long mtype; 
  3.   char mbuf[1024]; 
  4. }; 

3)msgsz:消息的大小。

4)msgflg:可以為IPC_NOWAIT或0,表示操作是阻塞式的還是非阻塞式的,設置為IPC_NOWAIT,在msgsnd()中,如果消息隊列已經滿了,則不會阻塞,立即返回-1(EAGAIN).

在msgrcv()中,如果消息隊列為空,則不做等待,立即返回-1(ENOMSG),設置為0,在msgsnd()中,進程阻塞直到(a)有空間可以容納要發送的消息;或(b)從系統中刪除了此隊列(返回EIDRM);或(c)捕捉到一個信號,并從信號處理程序返回(返回EINTR)。

在msgrcv()中,進程阻塞直到(a)有了指定類型的消息;或(b)從系統中刪除了此隊列(返回EIDRM);或(c)捕捉到一個信號并從信號處理程序返回(返回EINTR)。

5)msgtype:用于msgrcv()函數,指定消息的類型。相當于區分消息類別的標志位。

msgtype = 0,返回消息隊列中的第一個消息。

返回值:

msgsnd(),成功返回0,出錯返回-1。

msgrcv(),成功返回消息數據部分的長度,出錯返回-1。

例子程序:test3.c,代碼如下:

  1. #include <sys/types.h> 
  2. #include <sys/ipc.h> 
  3. #include <sys/msg.h> 
  4. #include <stdio.h> 
  5. #include <errno.h> 
  6. typedef struct 
  7.  long mtype; 
  8.  char mbuf[1024]; 
  9. }mymsg; 
  10. int main(void) 
  11.  int i; 
  12.  int msgid1, msgid2; 
  13.  mymsg message1, message2, message3; 
  14.  
  15.  printf("this is test3!\n"); 
  16.  
  17.  msgid1 = msgget(1002, 0666|IPC_CREAT);//key 1002 
  18.  if (msgid1 < 0) 
  19.  { 
  20.   printf("create key=1002 error, errno=%d\n", errno); 
  21.   exit(-1); 
  22.  } 
  23.  msgid2 = msgget(1003, 0666|IPC_CREAT);//key 1003 
  24.  if (msgid2 < 0) 
  25.  { 
  26.   printf("create key=1003 error, errno=%d\n", errno); 
  27.   exit(-1); 
  28.  } 
  29.  //初始化 
  30.  message1.mtype = 1;//設定一個消息類型 
  31.  memcpy(message1.mbuf, "first message", 13); 
  32.  message3.mtype = 1; 
  33.  memcpy(message3.mbuf, "hello test4.", 12); 
  34.  
  35.  //test3進程在msgid1上發消息 
  36.  i = msgsnd(msgid1, (void *)&message1, strlen(message1.mbuf)+1, 0); 
  37.  if (i < 0) 
  38.  { 
  39.   printf("send message1 error, errno=%d\n", errno); 
  40.   exit(-1); 
  41.  } 
  42.  
  43.  //test3進程從msgid1取消息,存到message2中 
  44.  i = msgrcv(msgid1, (void *)&message2, 1024, 0, 0); 
  45.  if (i < 0) 
  46.  { 
  47.   printf("rev error, errno=%d\n", errno); 
  48.   exit(-1); 
  49.  } 
  50.  else 
  51.  { 
  52.   //顯示取出的消息 
  53.   printf("%s\n", message2.mbuf); 
  54.  } 
  55.  //test3進程在msgid2上發消息 
  56.  i = msgsnd(msgid2, (void *)&message3, strlen(message3.mbuf)+1, 0); 
  57.  if (i < 0) 
  58.  { 
  59.   printf("send message3 error, errno=%d\n", errno); 
  60.   exit(-1); 
  61.  } 
  62.  
  63.  return 0; 

例子程序:test4.c,代碼如下:

  1. #include <sys/types.h> 
  2. #include <sys/ipc.h> 
  3. #include <sys/msg.h> 
  4. #include <stdio.h> 
  5. #include <errno.h> 
  6. typedef struct 
  7.  long mtype; 
  8.  char mbuf[1024]; 
  9. }mymsg; 
  10. int main(void) 
  11.  int i, j; 
  12.  mymsg message; 
  13.  
  14.  printf("this is test4!\n"); 
  15.  
  16.  i = msgget(1003, 0666|IPC_CREAT); 
  17.  if (i < 0) 
  18.  { 
  19.   printf("create key=1003 error, errno=%d\n", errno); 
  20.   exit(-1); 
  21.  } 
  22.  
  23.  //test4進程在key=1003的消息隊列上取消息 
  24.  j = msgrcv(i, (void *)&message, 1024, 0, 0); 
  25.  if (j < 0) 
  26.  { 
  27.   printf("rev error, errno=%d\n", errno); 
  28.   exit(-1); 
  29.  } 
  30.  else 
  31.  { 
  32.   //顯示取出的消息 
  33.   printf("%s\n", message.mbuf); 
  34.  } 
  35.  
  36.  return 0; 

開兩個終端,一個執行test3,另一個執行test4.

test3執行結果,代碼如下:

  1. [root@server ~]# ./test3 
  2. this is test3! 
  3. first message 

ipcs命令能看到key=1003的消息隊列中有一條消息,使用了13字節長度,代碼如下:

  1. key        msqid      owner      perms      used-bytes   messages 
  2. 0x000003ea 98305      root       666        0            0        
  3. 0x000003eb 131074     root       666        13           1        
  4. //test4執行結果: 
  5. [root@server ~]# ./test4 
  6. this is test4! 
  7. hello test4. 

以上.

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 新丰县| 江油市| 新巴尔虎左旗| 宁国市| 余姚市| 海晏县| 天祝| 沙雅县| 伊吾县| 肇州县| 西丰县| 东光县| 黔西县| 达州市| 嘉黎县| 合肥市| 龙井市| 临泽县| 科尔| 晴隆县| 汉沽区| 灌云县| 崇义县| 北碚区| 七台河市| 商丘市| 泸州市| 鹰潭市| 新闻| 荆州市| 防城港市| 醴陵市| 鄂托克旗| 定南县| 隆子县| 钦州市| 鄢陵县| 三穗县| 偏关县| 泾阳县| 兴安县|