色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

進程間通信的幾種實現方式

FPGA之家 ? 來源:嵌入式藝術 ? 作者:DonGe ? 2022-11-29 09:33 ? 次閱讀

在系統中,隨著我們的進程越來越多,難免不同進程之間要互相傳輸一些數據,那么這個時候該怎么辦呢?

下面主要簡單了解一下,進程間通信(InterProcess Communication,IPC)的幾種實現方式!

1、管道模型

管道模型與軟件生命周期模型——瀑布模型(Waterfall Model)很相似。

所謂的瀑布模型,其實就是將整個軟件開發過程分成多個階段,往往是上一個階段完全做完,才將輸出結果交給下一個階段。

ef3c1e2c-6f7b-11ed-8abf-dac502259ad0.pngimage-20220922134815245

還記得咱們最初學 Linux 命令的時候,有下面這樣一行命令:

ps -ef | grep 關鍵字 | awk '{print $2}' | xargs kill -9

這里面的豎線“|”就是一個管道。它會將前一個命令的輸出,作為后一個命令的輸入。

從管道的這個名稱可以看出來,管道是一種單向傳輸數據的機制,它其實是一段緩存,里面的數據只能從一端寫入,從另一端讀出。如果想互相通信,我們需要創建兩個管道才行。

管道又可以分為匿名管道和命名管道!

1.1 匿名管道

如上命令:

ps -ef | grep 關鍵字 | awk '{print $2}' | xargs kill -9

匿名管道:用"|” 表示的管道,意思就是這個類型的管道沒有名字,用完了就銷毀了。豎線代表的管道隨著命令的執行自動創建、自動銷毀。用戶甚至都不知道自己在用管道這種技術,就已經解決了問題。

1.2 命名管道

命名管道,這個類型的管道需要通過 mkfifo 命令顯式地創建。

mkfifo donge#建立一個管道

donge就是這個管道的名稱。管道以文件的形式存在,這也符合 Linux 里面一切皆文件的原則。

下面我們看一下文件類型

ls -l
prw-rw-r-- 1 dong dong     0 Sep 28 17:09 donge

可以看到,這個文件的類型是 p,就是 pipe 的意思。

往管道中寫入數據

echo "hello world" > donge

這個時候,管道里面的內容沒有被讀出,這個命令就是停在這里的,即進程被堵塞。

這說明當一個項目組要把它的輸出交接給另一個項目組做輸入,當沒有交接完畢的時候,前一個項目組是不能撒手不管的。

重新打開一個終端,讀出管道數據

cat < hello 
hello world

一方面,我們能夠看到,管道里面的內容被讀取出來,打印到了終端上;

另一方面,echo 那個命令正常退出了,也即交接完畢,前一個項目組就完成了使命,可以解散了。

管道通信,我們可以看出,瀑布模型的開發流程效率比較低下,因為團隊之間無法頻繁地溝通。而且,管道的使用模式,也不適合進程間頻繁的交換數據

2、消息隊列

ef560bd4-6f7b-11ed-8abf-dac502259ad0.pngimage-20220922135603302

消息隊列可以理解為發郵件,每一封郵件都視為一個獨立的數據單元,也就是消息體,每個消息體都是固定大小的存儲塊,在字節流上不連續

這個消息結構的定義我寫在下面了。這里面的類型 type 和正文 text 沒有強制規定,只要消息的發送方和接收方約定好即可。

struct msg_buffer {
    long mtype;
    char mtext[1024];
};

2.1 創建消息隊列

消息隊列的創建,需要用到msgget函數

int msgget(key_t key, int msgflg);
  • key:該參數是消息隊列的唯一標識,由ftok生成。

  • msgflg:取值有以下幾個選擇:IPC_CREATIPC_EXCL ,這兩個參數詳細的作用可以man msgflg看詳細介紹。

  • 返回值:返回一個近乎唯一的Message queue id

那么,key是如何由ftok生成的呢?

我們可以指定一個文件,調用ftok ,它會根據這個文件的 inode,生成一個近乎唯一的 key

key_t ftok(const char *pathname, int proj_id);
  • pathname:文件信息,必須指定在一個存在的,可訪問的文件
  • proj_id8bit的數據,0-255隨意設定

這樣就可以獲得一個近乎唯一的key了!

只要在這個消息隊列的生命周期內,這個文件不要被刪除就可以了。只要不刪除,無論什么時刻,再調用 ftok,也會得到同樣的 key。

綜上,創建一個消息隊列只需兩步:

①:ftok生成一個key

②:msgget生成一個消息隊列的ID

如下:

#include 
#include 
#include 
 
 
int main() {
  int messagequeueid;
  key_t key;
 
 
  if((key = ftok("/root/messagequeue/messagequeuekey", 1)) < 0)
  {
      perror("ftok error");
      exit(1);
  }
 
 
  printf("Message Queue key: %d.
", key);
 
 
  if ((messagequeueid = msgget(key, IPC_CREAT|0777)) == -1)
  {
      perror("msgget error");
      exit(1);
  }
 
 
  printf("Message queue id: %d.
", messagequeueid);
}

ftok要指定一個存在的文件,所以我們在執行之前,需要創建該文件。

查看消息隊列

System V IPC 體系有一個統一的命令行工具:ipcmkipcsipcrm 用于創建、查看和刪除 IPC 對象。

查看創建的IPC對象:ipcs -q

dong@ubuntu:~//Interprocess_Communication$ ipcs 

------ Message Queues --------
key        msqid      owner      perms      used-bytes   messages    
0x01110005 0          dong       777        0            0           

------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status      

------ Semaphore Arrays --------
key        semid      owner      perms      nsems

2.2 發送消息

消息隊列發送消息,主要調用msgsnd 函數

int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
  • msqid:該參數是msgget所得到的message queueid
  • msgp:消息結構體
struct msg_buffer {
    long mtype;
    char mtext[1024];
};
  • msgsz:表示消息結構體中,mtext最大長度
  • msgflg:一位掩碼,可取值有:IPC_NOWAITMSG_COPYMSG_EXCEPTMSG_NOERROR,取值說明可見man msgsnd

2.3 接收消息

消息隊列接收消息,主要調用msgrcv 函數

ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,
                      int msgflg);
  • msqid:該參數是msgget所得到的message queueid
  • msgp:消息結構體
  • msgsz:可接收數據最大長度
  • msgflg:一位掩碼,可取值有:IPC_NOWAITMSG_COPYMSG_EXCEPTMSG_NOERROR,取值說明可見man msgsnd

有了消息這種模型,兩個進程之間的通信就像咱們平時發郵件一樣,你來一封,我回一封,可以頻繁溝通了。

3、共享內存

ef63ce5e-6f7b-11ed-8abf-dac502259ad0.pngimage-20220924172026172

怎么理解共享內存呢?

我們知道每個進程都有自己獨立的虛擬內存空間不同的進程的虛擬內存空間映射到不同的物理內存中去。這個進程訪問 A 地址和另一個進程訪問 A 地址,其實訪問的是不同的物理內存地址,對于數據的增刪查改互不影響。

但是,咱們是不是可以變通一下,拿出一塊虛擬地址空間來,映射到相同的物理內存中。這樣這個進程寫入的東西,另外一個進程馬上就能看到了,都不需要拷貝來拷貝去,傳來傳去。

相比于消息隊列,共享內存的優勢在哪里呢?

  • 大數據傳輸:如果批量的大數據進行傳輸,使用郵件的方式,來去發送不及時,并且大小也有限制
  • 實時性:用共享內存,其可以大大節省通信時間

3.1 創建共享內存

我們可以創建一個共享內存,調用 shmget

int shmget(key_t key, size_t size, int shmflg);
  • key:和 msgget 里面的 key 一樣,都是唯一定位一個共享內存的對象
  • size:共享內存的大小
  • shmflg:其值可以取:IPC_CREATIPC_EXCLSHM_HUGETLBSHM_HUGE_2MB

返回值:共享內存的唯一ID

創建完畢之后,我們可以通過 ipcs 命令查看這個共享內存。

#ipcs --shmems
 
------ Shared Memory Segments ------ --------
key        shmid    owner perms    bytes nattch status
0x00000000 19398656 marc  600    1048576 2      dest

3.2 訪問共享內存

接下來,如果一個進程想要訪問這一段共享內存,需要將這個內存加載到自己的虛擬地址空間的某個位置,通過 shmat 函數,就是 attach 的意思。

void *shmat(int shmid, const void *shmaddr, int shmflg);
  • shmid:標識一個共享內存段的唯一ID
  • shmaddr:就是要指定 attach 到這個地方。但是這個地址的設定難度比較大,除非對于內存布局非常熟悉,否則可能會 attach到一個非法地址。所以,通常的做法是將 shmaddr設為 NULL,讓內核選一個合適的地址。
  • shmflg:一位掩碼,可取值:SHM_EXECSHM_RDONLYSHM_REMAP

返回值:為所連接的實際地址

3.3 關閉共享內存

如果共享內存使用完畢,可以通過 shmdt 解除綁定,然后通過 shmctl,將 cmd 設置為 IPC_RMID,從而刪除這個共享內存對象。

int shmdt(void *addr); 
int shmctl(int shmid, int cmd, struct shmid_ds *buf);

shmdt的參數addr:為shmat的返回值,表示卸載一片共享內存

shmctl的參數:

  • shm_idshmget的返回值,為共享內存的唯一ID
  • cmd:取值有:IPC_STATIPC_RMID等,見:man shmctl
  • buf:共享內存管理結構體。

3.4 信號

這里你是不是有一個疑問,如果兩個進程 attach 同一個共享內存,大家都往里面寫東西,很有可能就沖突了。例如兩個進程都同時寫一個地址,那先寫的那個進程會發現內容被別人覆蓋了。

所以,這里就需要一種保護機制,使得同一個共享的資源,同時只能被一個進程訪問。在 System V IPC 進程間通信機制體系中,早就想好了應對辦法,就是信號量(Semaphore。因此,信號量和共享內存往往要配合使用。

信號量和共享內存都比較復雜,兩者還要結合起來用,就更加復雜,它們內核的機制就更加復雜。這一節我們先不講。

4、信號

上面講的進程間通信的方式,都是常規狀態下的工作模式,對應到咱們平時的工作交接,收發郵件、聯合開發等,其實還有一種異常情況下的工作模式

例如出現線上系統故障,這個時候,什么流程都來不及了,不可能發郵件,也來不及開會,所有的架構師、開發、運維都要被通知緊急出動。所以,7 乘 24 小時不間斷執行的系統都需要有告警系統,一旦出事情,就要通知到人,哪怕是半夜,也要電話叫起來,處理故障。

信號可以在任何時候發送給某一進程,進程需要為這個信號配置信號處理函數。

Linux所支持的異常信號如下:

 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL       5) SIGTRAP
 6) SIGABRT      7) SIGBUS       8) SIGFPE       9) SIGKILL     10) SIGUSR1
11) SIGSEGV     12) SIGUSR2     13) SIGPIPE     14) SIGALRM     15) SIGTERM
16) SIGSTKFLT   17) SIGCHLD     18) SIGCONT     19) SIGSTOP     20) SIGTSTP
21) SIGTTIN     22) SIGTTOU     23) SIGURG      24) SIGXCPU     25) SIGXFSZ
26) SIGVTALRM   27) SIGPROF     28) SIGWINCH    29) SIGIO       30) SIGPWR
31) SIGSYS      34) SIGRTMIN    35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3
38) SIGRTMIN+4  39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8
43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7
58) SIGRTMAX-6  59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2
63) SIGRTMAX-1  64) SIGRTMAX

當某個信號發生的時候,就默認執行這個函數就可以了。這就相當于咱們運維一個系統應急手冊,當遇到什么情況,做什么事情,都事先準備好,出了事情照著做就可以了。

有點類似于異常中斷……

審核編輯:郭婷


聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 數據
    +關注

    關注

    8

    文章

    7134

    瀏覽量

    89513
  • 進程
    +關注

    關注

    0

    文章

    204

    瀏覽量

    13985

原文標題:原來\進程間通信/是這么回事......

文章出處:【微信號:zhuyandz,微信公眾號:FPGA之家】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    n母接頭的安裝方式有哪幾種

    等多個領域得到了廣泛應用。關于N型母接頭的安裝方式,雖然具體的安裝步驟可能因產品型號和制造商的不同而有所差異,但通常可以歸納為以下幾種主要方式:  這是N型母接
    的頭像 發表于 11-13 09:23 ?416次閱讀
    n母接頭的安裝<b class='flag-5'>方式</b>有哪<b class='flag-5'>幾種</b>

    socket 加密通信實現方式

    在網絡通信中,數據的安全性至關重要。Socket 編程作為網絡通信的基礎,實現加密通信是保護數據不被竊取或篡改的重要手段。 1. SSL/TLS 加密 SSL(Secure Socke
    的頭像 發表于 11-12 14:18 ?564次閱讀

    實現MCU與傳感器的通信方式

    在現代電子系統中,微控制器單元(MCU)與傳感器的通信實現智能控制和數據采集的基礎。隨著技術的發展,MCU與傳感器之間的通信方式也在不斷進化,以滿足更高的數據傳輸速率、更低的功耗和更
    的頭像 發表于 11-01 13:43 ?491次閱讀

    并聯電容器的補償方式有哪幾種

    并聯電容器是一種廣泛應用于電力系統和電子設備中的無功功率補償設備。它通過向系統提供無功功率,改善系統的功率因數,提高系統的穩定性和效率。并聯電容器的補償方式有很多種,下面將介紹幾種常見的補償方式
    的頭像 發表于 07-12 14:50 ?880次閱讀

    控制閥有哪幾種控制方式

    控制閥是工業自動化系統中的重要組成部分,其主要作用是控制流體的流量、壓力、溫度等參數,以滿足生產過程的需要。控制閥的控制方式有很多種,不同的控制方式適用于不同的應用場景。本文將詳細介紹控制閥的幾種
    的頭像 發表于 06-30 09:51 ?1015次閱讀

    ble_mesh節點如何實現以字符串的形式通信

    的想法是node1作為 ble mesh 的配置節點 同時利用bleg功能與手機app通信,從而控制整個ble_mesh 網絡) 3,如何配置 使已經配置好的 node 斷電后自動回復到之前的配置 4,ble_mesh 節點如何實現
    發表于 06-25 07:50

    工業控制設備主要有哪些有線通信技術?

    ? ? ? 工業控制設備的有線通信技術是實現工業自動化和智能制造的關鍵技術之一。隨著工業4.0和智能制造的快速發展,工業控制設備通信
    的頭像 發表于 06-23 16:38 ?956次閱讀

    鴻蒙開發通信與連接:ohos.rpc RPC通信

    本模塊提供進程通信能力,包括設備內的進程通信(IPC)和設備
    的頭像 發表于 06-21 09:40 ?608次閱讀
    鴻蒙開發<b class='flag-5'>通信</b>與連接:ohos.rpc RPC<b class='flag-5'>通信</b>

    連接器的連接方式幾種

    按照其連接方式可以分為以下幾種: 插頭式連接器:插頭式連接器是一種常見的連接方式,其特點是插頭和插座之間通過機械力實現連接。插頭式連接器廣泛應用于電子設備、
    的頭像 發表于 06-20 09:21 ?1689次閱讀

    工業控制設備主要有哪些有線通信技術

    工業控制設備的有線通信技術是實現工業自動化和智能制造的關鍵技術之一。隨著工業4.0和智能制造的快速發展,工業控制設備通信技術也在不斷地
    的頭像 發表于 06-11 10:51 ?793次閱讀

    串口屏的幾種安裝方式

    串口屏的幾種安裝方式
    的頭像 發表于 05-10 11:28 ?1673次閱讀

    進程通信的消息隊列介紹

    消息隊列是一種非常常見的進程通信方式
    的頭像 發表于 04-08 17:27 ?341次閱讀

    進程通信的信號問題分析

    Linux里面信號有60多個,分為標準信號和實時信號,編號從1到31,34到64。不同的內核版本略有區別。
    的頭像 發表于 04-07 10:16 ?453次閱讀

    java實現多線程的幾種方式

    Java實現多線程的幾種方式 多線程是指程序中包含了兩個或以上的線程,每個線程都可以并行執行不同的任務或操作。Java中的多線程可以提高程序的效率和性能,使得程序可以同時處理多個任務。 Java提供
    的頭像 發表于 03-14 16:55 ?780次閱讀

    鴻蒙OS跨進程IPC與RPC通信

    通過此代理讀寫數據來實現進程的數據通信,更具體的講,首先請求服務的(Client)一端會建立一個服務提供端(Server)的代理對象,這個代理對象具備和服務提供端(Server)一樣
    發表于 02-17 14:20
    主站蜘蛛池模板: 入禽太深在线观看免费高清 | 男人把女人桶到高潮嗷嗷叫 | 精品视频在线播放 | 亚洲午夜电影 | 暖暖 免费 高清 日本在线 | 亚洲AV 无码AV 中文字幕 | 大胸女晃奶动态图 | 夜色资源站国产www在线视频 | 亚洲国产在线播放在线 | 欧美人禽Zozo动人物杂交 | 亚洲精品综合在线影院 | 黑人强伦姧人妻日韩那庞大的 | 国产午夜一区二区三区免费视频 | 久久免费资源福利资源站 | 国产亚洲视频在线 | 第一次处破女18分钟免费 | 摸老师丝袜小内内摸出水 | 天天干夜夜叭 | 青柠在线电影高清免费观看 | 伦理片在线线看手机版 | 色婷婷激情AV精品影院 | 野花日本高清在线观看免费吗 | 日本熟妇乱妇熟色A片蜜桃亚洲 | 久久国产免费 | 国产精品一区二区资源 | 久久这里只有精品国产99 | 亚洲日韩视频免费观看 | 999在线观看精品免费 | 国产线精品视频在线观看 | 国产强奷糟蹋漂亮邻居在线观看 | 国产精品麻豆高潮刺激A片 国产精品麻豆a在线播放 | 神马老子影院午夜伦 | 国产精品无码亚洲区艳妇 | 爱如潮水3免费观看日本 | 精品久久久久久久国产潘金莲 | freevideoshd | 99精品视频免费在线观看 | 國產日韓亞洲精品AV | 东莞桑拿美女 | 国产精品久久久久久亚洲毛片 | 女人和男人插曲视频大全 |