電子產(chǎn)業(yè)一站式賦能平臺(tái)

PCB聯(lián)盟網(wǎng)

搜索
查看: 62|回復(fù): 0
收起左側(cè)

嵌入式Linux:進(jìn)程間通信機(jī)制

[復(fù)制鏈接]

660

主題

660

帖子

4567

積分

四級(jí)會(huì)員

Rank: 4

積分
4567
跳轉(zhuǎn)到指定樓層
樓主
發(fā)表于 2024-12-10 08:00:00 | 只看該作者 |只看大圖 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式

+ c/ d0 F0 J* {( H/ `7 s/ b點(diǎn)擊上方藍(lán)色字體,關(guān)注我們
% K( [/ M! K- S$ R6 }& ]7 F% Q( e. V& D  U3 @, @
1.1、UNIX IPC% E" X+ B# L1 z) F! W1 z" i( v& t
UNIX 傳統(tǒng)的 IPC 機(jī)制包括管道、FIFO 和信號(hào),這些機(jī)制最早由 UNIX 系統(tǒng)引入,適用于簡(jiǎn)單的單機(jī)進(jìn)程間通信。
5 k# e9 r' ]& F- n7 k
  • 管道(Pipe)' h( D- ^2 ^) x$ D
    一種單向、半雙工的通信機(jī)制,通常用于父子進(jìn)程間的數(shù)據(jù)傳遞。
    / D. A1 I4 a  R0 u, P父進(jìn)程可以寫入數(shù)據(jù),子進(jìn)程可以讀取。
  • FIFO(命名管道)2 r$ k( X# r$ N: w# E
    類似于管道,但通過(guò)文件系統(tǒng)實(shí)現(xiàn),任何進(jìn)程都可以通過(guò)路徑訪問(wèn)該管道,實(shí)現(xiàn)雙向通信。
  • 信號(hào)(Signal)
    + R3 V4 U7 a: c( o" Z信號(hào)是一種用于進(jìn)程間異步通知的機(jī)制,可以用于進(jìn)程之間的簡(jiǎn)單通信或事件通知,例如 SIGINT(Ctrl+C 發(fā)送的中斷信號(hào))。
    2 S; H! L' K1 x) m$ I5 }
    ( D& C' h1 C) n6 `4 H
    1.2、System V IPC' K- L! k! _* F, U
    System V IPC 是 UNIX 的增強(qiáng)版本,主要包括信號(hào)量、消息隊(duì)列和共享內(nèi)存,適合需要更復(fù)雜的進(jìn)程同步與數(shù)據(jù)共享的場(chǎng)景。
    ) C: T( m. ]9 \/ o( ?
  • 信號(hào)量(Semaphore)
    6 F$ d: Q  D' a; N2 ?' h用于進(jìn)程間的同步,通常用于控制對(duì)共享資源的訪問(wèn)。- e; ?1 v, O, f0 S  @; R2 P# K
    信號(hào)量用于防止多個(gè)進(jìn)程同時(shí)訪問(wèn)同一資源,避免資源爭(zhēng)用問(wèn)題。
  • 消息隊(duì)列(Message Queue)
    5 A( n  X& _6 R& s+ D; Z; T- z允許進(jìn)程以消息的形式發(fā)送和接收數(shù)據(jù)。7 P$ G0 e$ g5 v3 z! F
    消息隊(duì)列是一種先進(jìn)先出(FIFO)的結(jié)構(gòu),支持不同類型的消息,使得進(jìn)程可以基于消息類型進(jìn)行處理。
  • 共享內(nèi)存(Shared Memory)" C* X: N! T: ]2 _7 E+ c
    進(jìn)程之間共享同一塊內(nèi)存區(qū)域,允許它們直接讀寫數(shù)據(jù)。
    ' p# P% B7 `* ~/ ^" F. k這是最有效的 IPC 方式,因?yàn)閿?shù)據(jù)不需要在進(jìn)程之間復(fù)制。
    , ~! q) A4 f& M  J1 z7 A3 ]
    ' {6 A) H* \8 Q  ~) q3 m" p
    1.3、POSIX IPC0 u  {0 @- J' [7 ]4 ]8 w
    POSIX IPC 是 System V IPC 的改進(jìn)版本,旨在解決 System V IPC 在靈活性和可移植性上的一些不足。7 `0 U8 H& p' U
    ! y' D! b1 E! L
    POSIX 標(biāo)準(zhǔn)為 UNIX 系統(tǒng)間的兼容性提供了統(tǒng)一的接口,使得程序可以更方便地在不同的 UNIX 系統(tǒng)間移植。0 P, u5 _! B* x9 H) I+ ~
  • POSIX 信號(hào)量; _. Q5 k) p' K' v$ W
    與 System V 信號(hào)量類似,用于進(jìn)程同步,但提供了更靈活的接口和更強(qiáng)的實(shí)時(shí)性支持。
  • POSIX 消息隊(duì)列
    $ W: l) `; \: S; r2 {改進(jìn)了 System V 消息隊(duì)列,允許指定消息的優(yōu)先級(jí),并提供更簡(jiǎn)單的接口。
  • POSIX 共享內(nèi)存
    4 ~1 p3 ~8 Z% V6 E與 System V 共享內(nèi)存類似,但具有更好的兼容性和可移植性,接口設(shè)計(jì)更加現(xiàn)代化。8 |- u) w& v# d

    ; P- X( a7 Y  d+ ~, \5 s6 J/ @1.4、套接字(Socket)通信
    2 Z" q) w2 Z) Y) N% d4 M+ f  K- ?套接字是一種既可以用于本地進(jìn)程間通信,也可以用于網(wǎng)絡(luò)通信的機(jī)制,支持雙向數(shù)據(jù)傳輸。3 z& A6 z! n3 q" Z% ^0 G

    4 Y9 I) ]( a# X; `( @$ m" _基于套接字的 IPC 可以實(shí)現(xiàn)非常靈活的通信模式,例如客戶端-服務(wù)器架構(gòu),適合在多臺(tái)計(jì)算機(jī)之間傳遞數(shù)據(jù)。( v& Q' N# N- Z% F- ?% x
    ' c* Z- r  e0 t& J' {+ ~. R/ d
    各類 IPC 機(jī)制的對(duì)比和應(yīng)用場(chǎng)景:
    $ G! @$ h& l, [* g) R& R9 Q0 s$ ?  d) S  r4 ~* N4 \
    ' W: v. C" N* h9 w, O4 ?, w

    : K* U2 P' d' w5 C9 }. A. n: U1 u2
    # B& {. p5 R' @5 t5 u管道(Pipe)
    2 M9 l6 y* m5 p+ W/ y( r管道是一種半雙工(單向)的通信方式,通常用于父子進(jìn)程之間的通信。一個(gè)進(jìn)程可以向管道寫入數(shù)據(jù),另一個(gè)進(jìn)程從管道讀取數(shù)據(jù)。
    & P7 F0 a" U% t7 |
    5 H  ^2 g; B& t8 C0 l5 zLinux 提供了無(wú)名管道和命名管道兩種類型。
      [! o. g5 T1 O6 M: F# ^3 Z
  • 無(wú)名管道(Anonymous Pipe). B% M2 |; ]( F0 C
    只能在具有親緣關(guān)系的進(jìn)程間使用,比如父進(jìn)程和子進(jìn)程。
  • 命名管道(Named Pipe 或 FIFO)! i& [$ k% d' x8 f! o
    通過(guò)文件系統(tǒng)中的路徑來(lái)創(chuàng)建,任意進(jìn)程都可以訪問(wèn)。/ q) v" y1 L5 T+ C
    , e0 y2 B& Q. n4 d5 |' N

    ( r$ k1 I) m1 _" \示例2 L8 J# j+ I# h0 }% ~

    ) \6 s) Q6 S* D) N
  • int main() {    int fd[2];    pipe(fd); // 創(chuàng)建無(wú)名管道
    3 T; h+ G; p" S    if (fork() == 0) { // 子進(jìn)程        close(fd[0]); // 關(guān)閉讀取端        write(fd[1], "Hello, parent!", 15);        close(fd[1]);    } else { // 父進(jìn)程        char buffer[20];        close(fd[1]); // 關(guān)閉寫入端        read(fd[0], buffer, sizeof(buffer));        printf("Received: %s
    : I+ V  O4 t4 P& R", buffer);        close(fd[0]);    }    return 0;}' O& l" U, n4 d$ N0 b0 n0 W& U" E
    3" K; Q8 z0 W2 H- o. b0 q
    消息隊(duì)列(Message Queue)
    * h1 }4 ~; n7 J9 l" Q消息隊(duì)列是一種先進(jìn)先出的隊(duì)列,允許進(jìn)程以消息的形式發(fā)送和接收數(shù)據(jù)。
    & s4 Y' w* W9 X8 M4 n7 J4 h/ e0 f" ]) O" l& c- K
    消息隊(duì)列可以支持多種類型的消息,通過(guò)消息類型實(shí)現(xiàn)多種目的的通信。
    % H& ?, x' [4 A2 w. q0 Y  k0 T( ^3 u; K2 B0 V
    示例:進(jìn)程A可以向隊(duì)列發(fā)送一個(gè)帶有特定類型的消息,而進(jìn)程B可以根據(jù)消息類型進(jìn)行處理。! @! U0 k+ u* T$ K; W6 z

    6 G. _( ^! D) Q+ W$ Y+ S5 B. b
  • struct msgbuf {    long mtype;    char mtext[100];};9 y+ A' h2 |' l6 h1 Z4 S) X# R
    int main() {    key_t key = ftok("msgqueue", 65);    int msgid = msgget(key, 0666 | IPC_CREAT);    struct msgbuf message;4 P" s8 w2 |/ J6 E; L0 a6 n
        message.mtype = 1; // 消息類型    snprintf(message.mtext, sizeof(message.mtext), "Hello Message Queue");    msgsnd(msgid, &message, sizeof(message.mtext), 0);
    + A1 J0 e0 [/ R2 [    return 0;}8 d9 |( _6 w' V1 z9 N( E) ^
    4
    & O$ \  |" V5 C. W6 T1 |共享內(nèi)存(Shared Memory)
    * ^! N- Q* w( e7 P共享內(nèi)存是最快的 IPC 機(jī)制之一,因?yàn)檫M(jìn)程之間直接訪問(wèn)同一塊內(nèi)存區(qū)域,而不需要拷貝數(shù)據(jù)。
    8 b/ A! j' P( ?* n/ R) E
    # l  y- Y" e* }$ c9 ^8 D: X通常使用 shmget()、shmat() 和 shmdt() 函數(shù)進(jìn)行共享內(nèi)存的創(chuàng)建和訪問(wèn)。8 V& A/ E0 W! D  r) G3 L
    2 o+ a8 S: Z6 W* D# G7 w* S* y) N
    示例- A5 @) `  T5 b
    4 F5 c5 G& q- H' ~& A& O1 y! M
  • int main() {    key_t key = ftok("shmfile",65);    int shmid = shmget(key, 1024, 0666|IPC_CREAT);    char *str = (char*) shmat(shmid, (void*)0, 0);
    2 c( A1 Z) W; _! X    strcpy(str, "Hello Shared Memory");. B& a7 X: [0 s
        printf("Data written in memory: %s% C3 w4 H+ z% I! x
    ", str);    shmdt(str);
    6 C% o7 Q! N* T9 K- K7 Z* U    return 0;}; V9 H# y7 {+ @
    51 d  ~: J& M4 @, n5 }2 N& l
    信號(hào)量(Semaphore)
    7 |# ?' `% Q4 C' v. e( s信號(hào)量是一種用于進(jìn)程同步的機(jī)制,通常用于控制多個(gè)進(jìn)程對(duì)共享資源的訪問(wèn)。
    - W% \/ W6 A0 [: n( Z# a$ `  a2 A! _6 |
    嵌入式系統(tǒng)中,信號(hào)量通常用來(lái)避免多個(gè)進(jìn)程同時(shí)訪問(wèn)同一資源,防止數(shù)據(jù)競(jìng)爭(zhēng)。: K2 W0 _; o. O

    9 O! @/ K2 R, I$ j$ B+ E+ f" z示例:信號(hào)量可以通過(guò) semget() 和 semop() 函數(shù)來(lái)操作,用于鎖定或解鎖資源。  k, J2 ]# I7 a" w% g/ r

    $ b% K/ ?9 M* ~* q7 s- k
  • int main() {    key_t key = ftok("semfile",65);    int semid = semget(key, 1, 0666 | IPC_CREAT);    struct sembuf sem_lock = {0, -1, 0}; // 減1操作    struct sembuf sem_unlock = {0, 1, 0}; // 加1操作
    6 R# D, I, C4 |# B- z2 d- }2 p* e    semop(semid, &sem_lock, 1); // 上鎖    printf("Critical section
    ) I" L  y4 Z& [! r& t3 f+ u' l7 m. {");    semop(semid, &sem_unlock, 1); // 解鎖! C4 m4 x% v" g2 j2 m  b1 q
        return 0;}
    : q- P/ C4 z4 Y6, M, m) K! V6 \9 L% e! i
    套接字(Socket)% a  w, o4 V5 [' x
    套接字不僅支持本地進(jìn)程間通信,還可以用于網(wǎng)絡(luò)通信。
    $ T/ |. a6 ?. o
    ; Y  p5 B! U% Q4 w$ s) z基于套接字的 IPC 支持雙向通信,比較靈活,適合嵌入式系統(tǒng)中進(jìn)程之間需要頻繁且復(fù)雜的數(shù)據(jù)交互的情況。
    * g6 T" ?( w" F, F6 [0 l5 W
    2 o7 h+ r' L' S7 M, l. U$ W示例
    + Y! v1 t4 t8 [5 ]! K
    ( g+ c1 J' k8 e
  • int main() {    int sv[2];    socketpair(AF_UNIX, SOCK_STREAM, 0, sv);
    / [- u3 [0 L8 i" B* R! y2 Y1 F5 G0 E( a    if (fork() == 0) { // 子進(jìn)程        close(sv[0]);        write(sv[1], "Hello from child", 16);        close(sv[1]);    } else { // 父進(jìn)程        char buffer[20];        close(sv[1]);        read(sv[0], buffer, sizeof(buffer));        printf("Received: %s+ |( \( U" N( U8 v
    ", buffer);        close(sv[0]);    }    return 0;}
    8 z# x( m- y! T; L( p: n. \71 R8 P+ h  t% W2 V( {
    信號(hào)(Signal)! s5 ^7 h3 t2 n4 W5 E
    信號(hào)是用來(lái)通知進(jìn)程發(fā)生某種事件的機(jī)制。進(jìn)程可以捕獲、忽略或處理信號(hào),典型的信號(hào)包括 SIGINT(中斷信號(hào))和 SIGKILL(殺死進(jìn)程信號(hào))。8 `( _* a: w0 F! x7 j
    , T5 s. N+ h8 f( e) q. p/ r
    示例:處理 SIGINT 信號(hào)(Ctrl+C)。
    , P+ P! q6 l0 K* u; ?9 k; ?1 M5 I/ x6 `# j' \! X
  • void sigint_handler(int sig) {    printf("Caught signal %d' L$ X9 X9 ~/ ~1 |9 d# Q9 K' u0 t, H  a
    ", sig);}1 ], G& a; G, M+ U8 N) r5 q+ v
    int main() {    signal(SIGINT, sigint_handler);    while (1) {        printf("Running...6 C& X8 Y6 g2 k1 N4 A. w/ K) h
    ");        sleep(1);    }    return 0;}
    4 d8 @! U3 L) @% a& j$ K" \進(jìn)程間通信的機(jī)制多種多樣,選擇合適的方式取決于應(yīng)用場(chǎng)景的需求。2 I/ k8 v' `" n) Q& |4 ]1 l0 e. ]6 P

    5 Y/ M' Y" q0 W8 g' b
    ! x- k$ K2 B+ y7 ~! |+ Q* a點(diǎn)擊閱讀原文,更精彩~
  • 發(fā)表回復(fù)

    本版積分規(guī)則


    聯(lián)系客服 關(guān)注微信 下載APP 返回頂部 返回列表