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

      網(wǎng)友投稿 758 2025-04-01

      擁有夢(mèng)想是一種智力,實(shí)現(xiàn)夢(mèng)想是一種能力


      概述

      若是一個(gè)多線程的進(jìn)程,由于各個(gè)線程共享一個(gè)地址空間,可以直接通過(guò)變量的形式進(jìn)行通信。而進(jìn)程,由于各個(gè)進(jìn)程獨(dú)占一個(gè)地址空間,我們需要一種通信機(jī)制來(lái)完成進(jìn)程間的數(shù)據(jù)交互。本章介紹的是消息隊(duì)列,進(jìn)程間的通信機(jī)制有以下幾種:

      無(wú)名管道(pipe)

      有名管道 (fifo)

      信號(hào)(signal)

      System ?V ?IPC

      共享內(nèi)存(share memory)

      消息隊(duì)列(message queue)

      信號(hào)燈集(semaphore set)

      套接字(socket)

      之間有區(qū)分與各自的運(yùn)用場(chǎng)景,其中套接字通常使用在網(wǎng)絡(luò)服務(wù),其他只能在本地場(chǎng)景下使用。筆者以后會(huì)逐一學(xué)習(xí),本章介紹System ?V ?IPC中的消息隊(duì)列。

      System ?V ?IPC

      System ?V?IPC引入了三種高級(jí)進(jìn)程間的通信機(jī)制。一個(gè)IPC對(duì)象包含消息隊(duì)列、共享內(nèi)寸和信號(hào)量。

      共享內(nèi)存

      消息隊(duì)列

      信號(hào)燈集

      System V IPC對(duì)象

      每個(gè)IPC對(duì)象有唯一的ID

      IPC對(duì)象創(chuàng)建后一直存在,直到被顯式地刪除

      每個(gè)IPC對(duì)象有一個(gè)關(guān)聯(lián)的KEY(其中進(jìn)程的私有對(duì)象KTY值為0)

      命令查看IPC對(duì)象

      IPC對(duì)象是全局對(duì)象,可用ipcs,ipcrm等命令查看或刪除

      ipcs?-q:?只顯示消息隊(duì)列

      ipcs?-s:?只顯示信號(hào)量

      ipcs?-m:?只顯示共享內(nèi)存

      ipcs?–help:?其他的參數(shù)

      函數(shù)操作

      創(chuàng)建一個(gè)IPC對(duì)象

      進(jìn)程創(chuàng)建IPC對(duì)象之前,先f(wàn)tok生成一個(gè)key值。

      #include ?

      #include

      key_t ?ftok(const char *path, ?int proj_id);

      成功時(shí)返回合法的key值,失敗時(shí)返回EOF

      path ?存在且可訪問(wèn)的文件的路徑

      proj_id ?用于生成key的數(shù)字,不能為0

      消息隊(duì)列

      消息隊(duì)列是System V IPC對(duì)象的一種,由消息隊(duì)列ID來(lái)唯一標(biāo)識(shí)。消息隊(duì)列就是一個(gè)消息的列表。用戶可以在消息隊(duì)列中添加消息、讀取消息等

      特點(diǎn)是消息隊(duì)列可以按照類型來(lái)發(fā)送/接收消息。

      消息隊(duì)列結(jié)構(gòu)

      消息格式

      通信雙方首先定義好統(tǒng)一的消息格式,用戶根據(jù)應(yīng)用需求定義結(jié)構(gòu)體類型

      其中,首成員類型為long,代表消息類型(正整數(shù)),其他成員都屬于消息正文

      typedef struct {

      long mtype;

      char mtext[64];

      } MSG;

      消息隊(duì)列使用步驟

      打開(kāi)/創(chuàng)建消息隊(duì)列 ? msgget

      向消息隊(duì)列發(fā)送消息 ? msgsnd

      從消息隊(duì)列接收消息 ? msgrcv

      控制消息隊(duì)列 ? msgctl

      消息隊(duì)列創(chuàng)建/打開(kāi) – msgget

      #include

      #include

      int msgget(key_t key, int msgflg);

      成功時(shí)返回消息隊(duì)列的id,失敗時(shí)返回EOF

      key 和消息隊(duì)列關(guān)聯(lián)的key ?IPC_PRIVATE 或 ftok

      msgflg ?標(biāo)志位 ?IPC_CREAT|0666

      消息發(fā)送 – msgsnd

      #include

      #include

      int msgsnd(int msgid, const void *msgp, size_t size,

      int msgflg);

      成功時(shí)返回0,失敗時(shí)返回-1

      msgid ? 消息隊(duì)列id

      msgp ? ?消息緩沖區(qū)地址

      size ? ?消息正文長(zhǎng)度

      msgflg ? 標(biāo)志位 0 或 IPC_NOWAIT

      消息接收 – msgrcv

      #include

      #include

      int msgrcv(int msgid, void *msgp, size_t size, long msgtype,

      int msgflg);

      成功時(shí)返回收到的消息長(zhǎng)度,失敗時(shí)返回-1

      msgid ? 消息隊(duì)列id

      msgp ? 消息緩沖區(qū)地址

      size ? 指定接收的消息長(zhǎng)度

      msgtype ? 指定接收的消息類型

      msgflg ? 標(biāo)志位 ? 0 或 IPC_NOWAIT

      控制消息隊(duì)列 – msgctl

      #include

      #include

      int msgctl(int msgid, int cmd, struct msqid_ds *buf);

      成功時(shí)返回0,失敗時(shí)返回-1

      msgid ? ?消息隊(duì)列id

      cmd ? ?要執(zhí)行的操作 ?IPC_STAT / IPC_SET / IPC_RMID

      buf ? 存放消息隊(duì)列屬性的地址

      示例

      兩個(gè)進(jìn)程通過(guò)消息隊(duì)列輪流將鍵盤(pán)輸入的字符串發(fā)送給對(duì)方,接收并打印對(duì)方發(fā)送的消息

      A.c

      #include

      #include

      #include

      #include

      #include

      typedef struct {

      long mtype;

      char mtext[64];

      } MSG;

      #define LEN (sizeof(MSG) – sizeof(long))

      #define TypeA 100

      #define TypeB 200

      int main()

      {

      int msgid;

      key_t key;

      MSG buf;

      if ((key = ftok(“.”, ‘q’)) == -1)

      {

      perror(“ftok”);

      exit(-1);

      }

      if ((msgid = msgget(key, IPC_CREAT|0666)) < 0)

      {

      perror(“msgget”);

      exit(-1);

      }

      while ( 1 )

      {

      buf.mtype = TypeB;

      printf("input > ");

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

      fgets(buf.mtext, 64, stdin);

      msgsnd(msgid, &buf, LEN, 0);

      if (strcmp(buf.mtext, "quit\n") == 0) exit(0);

      msgrcv(msgid, &buf, LEN, TypeA, 0);

      if (strcmp(buf.mtext, "quit\n") == 0) break;

      printf("recv message : %s", buf.mtext);

      }

      msgctl(msgid, IPC_RMID, NULL);

      return 0;

      }

      B.c

      #include

      #include

      #include

      #include

      #include

      typedef struct {

      long mtype;

      char mtext[64];

      } MSG;

      #define LEN (sizeof(MSG) – sizeof(long))

      #define TypeA 100

      #define TypeB 200

      int main()

      {

      int msgid;

      key_t key;

      MSG buf;

      if ((key = ftok(“.”, ‘q’)) == -1)

      {

      perror(“ftok”);

      exit(-1);

      }

      if ((msgid = msgget(key, IPC_CREAT|0666)) < 0)

      {

      perror(“msgget”);

      exit(-1);

      }

      while ( 1 )

      {

      msgrcv(msgid, &buf, LEN, TypeB, 0);

      if (strcmp(buf.mtext, "quit\n") == 0) break;

      printf("recv message : %s", buf.mtext);

      buf.mtype = TypeA;

      printf("input > ");

      fgets(buf.mtext, 64, stdin);

      msgsnd(msgid, &buf, LEN, 0);

      if (strcmp(buf.mtext, "quit\n") == 0) exit(0);

      }

      msgctl(msgid, IPC_RMID, NULL);

      return 0;

      }

      這樣,當(dāng)A是發(fā)送端,B進(jìn)程在等待接收。B接收到數(shù)據(jù),成為發(fā)送端,A進(jìn)程等待接收。直到一方發(fā)送'quit',發(fā)送端進(jìn)程結(jié)束,接收端刪除消息隊(duì)列,結(jié)束。

      注意的是,進(jìn)程發(fā)送對(duì)方的類型,接收時(shí)指定自己的類型。

      Linux 任務(wù)調(diào)度

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      上一篇:移動(dòng)和復(fù)制對(duì)象(移動(dòng)和復(fù)制對(duì)象都要借助什么來(lái)完成)
      下一篇:Excel中隔行求和的技巧(怎么隔行求和excel表格)
      相關(guān)文章
      亚洲片一区二区三区| 亚洲人成电影网站| 亚洲国产美女在线观看| 久久亚洲精品国产精品黑人| 亚洲欧美日韩国产精品一区| 亚洲国产综合精品中文第一区| 精品亚洲综合在线第一区| 久久精品国产精品亚洲艾草网美妙 | 亚洲av无码专区在线播放| 中文亚洲AV片在线观看不卡 | 亚洲国产午夜中文字幕精品黄网站 | 亚洲国产精品丝袜在线观看| 久久精品国产亚洲AV| 亚洲av无码一区二区三区在线播放| 亚洲精品无码永久在线观看男男| 中国china体内裑精亚洲日本| 亚洲国产精品免费观看 | 亚洲日韩一页精品发布| 亚洲人成精品久久久久| 情人伊人久久综合亚洲| 亚洲国产精品自在线一区二区 | 亚洲av无码日韩av无码网站冲| 亚洲高清毛片一区二区| 亚洲日韩在线中文字幕综合| 亚洲第一视频在线观看免费| 国产L精品国产亚洲区久久| 亚洲日韩中文无码久久| 亚洲综合在线观看视频| 亚洲国产成人在线视频| 亚洲综合av一区二区三区| 亚洲日韩精品国产一区二区三区| 久久精品国产亚洲AV电影网| 亚洲国产精品无码久久久久久曰| 国产精品亚洲高清一区二区 | 亚洲精品无码日韩国产不卡av| AV激情亚洲男人的天堂国语| 亚洲JIZZJIZZ中国少妇中文| 亚洲一区二区三区影院| 久久亚洲国产精品| 亚洲国产成人无码av在线播放| 亚洲乱人伦中文字幕无码|