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

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

搜索
查看: 64|回復(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覽 |閱讀模式
) D, l" y8 ]+ s
點(diǎn)擊上方藍(lán)色字體,關(guān)注我們) r" H9 ~; f* ~% ]1 y: \3 q
3 J' ?8 I0 C1 `; v# a. `
1.1、UNIX IPC! f! l' Z. t) n" q$ `/ |. W8 i
UNIX 傳統(tǒng)的 IPC 機(jī)制包括管道、FIFO 和信號(hào),這些機(jī)制最早由 UNIX 系統(tǒng)引入,適用于簡(jiǎn)單的單機(jī)進(jìn)程間通信。
3 l! M. y! ]$ l/ B$ }  A/ l
  • 管道(Pipe)
    " }0 s& h, ~& e! O一種單向、半雙工的通信機(jī)制,通常用于父子進(jìn)程間的數(shù)據(jù)傳遞。( z0 {7 X+ ^8 ?
    父進(jìn)程可以寫入數(shù)據(jù),子進(jìn)程可以讀取。
  • FIFO(命名管道)
    : h& X- W+ j+ S3 J& }' }類似于管道,但通過(guò)文件系統(tǒng)實(shí)現(xiàn),任何進(jìn)程都可以通過(guò)路徑訪問(wèn)該管道,實(shí)現(xiàn)雙向通信。
  • 信號(hào)(Signal)
    1 o& ?! s9 W5 V5 H. U3 ?' |信號(hào)是一種用于進(jìn)程間異步通知的機(jī)制,可以用于進(jìn)程之間的簡(jiǎn)單通信或事件通知,例如 SIGINT(Ctrl+C 發(fā)送的中斷信號(hào))。
    7 Z' j% N+ i  S+ l

    , F  l" R; A* }" C# ~1 G3 B1.2、System V IPC. L% M2 r5 E# \8 P: E5 Z) M5 ~# X
    System V IPC 是 UNIX 的增強(qiáng)版本,主要包括信號(hào)量、消息隊(duì)列和共享內(nèi)存,適合需要更復(fù)雜的進(jìn)程同步與數(shù)據(jù)共享的場(chǎng)景。! u, R0 c) d5 l6 t0 a5 v
  • 信號(hào)量(Semaphore)  y/ A" w- l8 O0 r
    用于進(jìn)程間的同步,通常用于控制對(duì)共享資源的訪問(wèn)。3 w+ i* @- Y$ m" x/ ^8 U+ m
    信號(hào)量用于防止多個(gè)進(jìn)程同時(shí)訪問(wèn)同一資源,避免資源爭(zhēng)用問(wèn)題。
  • 消息隊(duì)列(Message Queue)
    9 U3 l$ Q( w2 {允許進(jìn)程以消息的形式發(fā)送和接收數(shù)據(jù)。1 u7 X, v" N' Y- V0 N
    消息隊(duì)列是一種先進(jìn)先出(FIFO)的結(jié)構(gòu),支持不同類型的消息,使得進(jìn)程可以基于消息類型進(jìn)行處理。
  • 共享內(nèi)存(Shared Memory)% r3 F( n8 S$ `: Q% C  X. H# J% G) \
    進(jìn)程之間共享同一塊內(nèi)存區(qū)域,允許它們直接讀寫數(shù)據(jù)。& `3 [- @! u" E9 j: O# M; M9 E
    這是最有效的 IPC 方式,因?yàn)閿?shù)據(jù)不需要在進(jìn)程之間復(fù)制。
    : C% G$ m3 p$ z: _! F) y) `
    " k. N) z& ?1 x- G/ J
    1.3、POSIX IPC, R" X. _5 I3 H- S( n( p
    POSIX IPC 是 System V IPC 的改進(jìn)版本,旨在解決 System V IPC 在靈活性和可移植性上的一些不足。+ Z; m, v+ j' i4 Q- Y
    0 Y& A7 `$ u! q3 }
    POSIX 標(biāo)準(zhǔn)為 UNIX 系統(tǒng)間的兼容性提供了統(tǒng)一的接口,使得程序可以更方便地在不同的 UNIX 系統(tǒng)間移植。) q' d/ d0 I7 |( {
  • POSIX 信號(hào)量
    + O3 {. |- M. k# H8 |與 System V 信號(hào)量類似,用于進(jìn)程同步,但提供了更靈活的接口和更強(qiáng)的實(shí)時(shí)性支持。
  • POSIX 消息隊(duì)列
    * B/ i+ Z4 Z' T; j- J改進(jìn)了 System V 消息隊(duì)列,允許指定消息的優(yōu)先級(jí),并提供更簡(jiǎn)單的接口。
  • POSIX 共享內(nèi)存+ _) x" A, ]  e$ y4 H- F1 U) ~
    與 System V 共享內(nèi)存類似,但具有更好的兼容性和可移植性,接口設(shè)計(jì)更加現(xiàn)代化。' l, c) r8 Q3 ~. \5 [

    ' u/ N+ K$ ~: U4 J6 ~0 _1 L! b1.4、套接字(Socket)通信) ~' q, \, I: G$ }6 y- n
    套接字是一種既可以用于本地進(jìn)程間通信,也可以用于網(wǎng)絡(luò)通信的機(jī)制,支持雙向數(shù)據(jù)傳輸。* E6 d, R7 u' |: [) \+ ^
    $ ~7 a' k; M7 J6 b
    基于套接字的 IPC 可以實(shí)現(xiàn)非常靈活的通信模式,例如客戶端-服務(wù)器架構(gòu),適合在多臺(tái)計(jì)算機(jī)之間傳遞數(shù)據(jù)。
    % j( B' ^1 ]6 v7 J) P  Q2 {# I& z: v7 u& o+ ^$ o! l
    各類 IPC 機(jī)制的對(duì)比和應(yīng)用場(chǎng)景:
    $ s& }$ H7 F. A$ b( d- j8 I9 Q% w! Y2 v% A1 R( C/ F

    . g$ M3 k. O  U+ T& l4 p9 @
    7 `9 m3 H7 |$ P$ q- P, Q2
    0 R3 \5 s6 _( R# m- @9 l管道(Pipe)
    3 Z' }3 y- Z, J* ?; _管道是一種半雙工(單向)的通信方式,通常用于父子進(jìn)程之間的通信。一個(gè)進(jìn)程可以向管道寫入數(shù)據(jù),另一個(gè)進(jìn)程從管道讀取數(shù)據(jù)。' x% y6 H- \" x0 D: I4 p3 l
    ) N9 Q- `  F' i7 O3 v
    Linux 提供了無(wú)名管道和命名管道兩種類型。
    . p. J0 s, D) }+ {" G' O, H5 h$ \, s
  • 無(wú)名管道(Anonymous Pipe)* z3 c6 f; y' Q% R9 `
    只能在具有親緣關(guān)系的進(jìn)程間使用,比如父進(jìn)程和子進(jìn)程。
  • 命名管道(Named Pipe 或 FIFO)
    3 b4 C5 i7 J  u, H  [通過(guò)文件系統(tǒng)中的路徑來(lái)創(chuàng)建,任意進(jìn)程都可以訪問(wèn)。. Y; E7 s$ V& g
    ! n- O! r0 |2 l
    + z) {0 ?2 @/ J1 q+ T, V9 C
    示例- k) s# z4 \* @1 c6 f" |
    " e6 O2 A; `/ f( d3 \' N
  • int main() {    int fd[2];    pipe(fd); // 創(chuàng)建無(wú)名管道. Y, _4 g. s) Q( }3 q) m
        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$ v6 j9 M& X5 O, A% C
    ", buffer);        close(fd[0]);    }    return 0;}' s. w: ~( l9 e/ m' V
    3
    ! k/ K4 _7 U7 O! X- q  l消息隊(duì)列(Message Queue)
    6 s4 p% v" V+ z4 g. F- A2 u9 \消息隊(duì)列是一種先進(jìn)先出的隊(duì)列,允許進(jìn)程以消息的形式發(fā)送和接收數(shù)據(jù)。9 Z% h2 ]9 T. H" ~

    ' Q$ C$ _7 [1 b& o! |3 ~$ q% V消息隊(duì)列可以支持多種類型的消息,通過(guò)消息類型實(shí)現(xiàn)多種目的的通信。1 M6 G. T6 C3 o: ]( w1 G

    % C5 h, C4 E" C示例:進(jìn)程A可以向隊(duì)列發(fā)送一個(gè)帶有特定類型的消息,而進(jìn)程B可以根據(jù)消息類型進(jìn)行處理。: }1 A8 K5 g: B  }; Y; t$ G

    " R1 A1 P5 R  J  O% W
  • struct msgbuf {    long mtype;    char mtext[100];};% @$ X! A& K% w
    int main() {    key_t key = ftok("msgqueue", 65);    int msgid = msgget(key, 0666 | IPC_CREAT);    struct msgbuf message;9 i* g# \& m: ^
        message.mtype = 1; // 消息類型    snprintf(message.mtext, sizeof(message.mtext), "Hello Message Queue");    msgsnd(msgid, &message, sizeof(message.mtext), 0);
    " _6 c$ l6 `0 ]    return 0;}
    0 x( L7 d5 m3 W: v% Y44 s7 i& Q( T. ?( T
    共享內(nèi)存(Shared Memory)) |$ N; K' G2 g6 v- c1 C. C+ o% i
    共享內(nèi)存是最快的 IPC 機(jī)制之一,因?yàn)檫M(jìn)程之間直接訪問(wèn)同一塊內(nèi)存區(qū)域,而不需要拷貝數(shù)據(jù)。
    + G- U/ e4 c' v! ]
    ) d/ T# ~' B! R. C9 I- D2 J$ C, q通常使用 shmget()、shmat() 和 shmdt() 函數(shù)進(jìn)行共享內(nèi)存的創(chuàng)建和訪問(wèn)。
    * K. f2 {; h- p4 j
    / @& t- a, C& V! q6 h/ v示例" E$ g5 y5 ^1 ]
    ! }/ M* a' T8 J$ R
  • int main() {    key_t key = ftok("shmfile",65);    int shmid = shmget(key, 1024, 0666|IPC_CREAT);    char *str = (char*) shmat(shmid, (void*)0, 0);( A& Y2 o# l& F( k
        strcpy(str, "Hello Shared Memory");. ]. e, y$ h: a
        printf("Data written in memory: %s
      P# U8 f* I3 c; T  j", str);    shmdt(str);7 ^5 H# @3 i  ^! I
        return 0;}# g; G5 S/ _- w2 C: x1 j: e
    58 y9 G9 [% y! ^4 F3 r! g& U
    信號(hào)量(Semaphore)6 S8 W, Y# _& E( ]/ l; p$ X
    信號(hào)量是一種用于進(jìn)程同步的機(jī)制,通常用于控制多個(gè)進(jìn)程對(duì)共享資源的訪問(wèn)。4 n# x6 h; N+ Y8 z
    0 z3 k* {! x! {
    嵌入式系統(tǒng)中,信號(hào)量通常用來(lái)避免多個(gè)進(jìn)程同時(shí)訪問(wèn)同一資源,防止數(shù)據(jù)競(jìng)爭(zhēng)。6 F1 d& `$ P! O( x" T

    2 a% x1 {- W4 |" Z! D$ d3 q示例:信號(hào)量可以通過(guò) semget() 和 semop() 函數(shù)來(lái)操作,用于鎖定或解鎖資源。
    ) S( E) E$ x* X& m: y0 c
    7 {' K- W( ~4 P2 t  s- X- Q5 ~, G
  • 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操作
    " E! N. H7 c+ J# I    semop(semid, &sem_lock, 1); // 上鎖    printf("Critical section
    . P+ f( H; K3 L/ l" X# ]! A! R) T");    semop(semid, &sem_unlock, 1); // 解鎖
    7 V$ ?' r/ W' j; r6 L# |    return 0;}$ V/ v- c) c5 q5 m, Z* S( p! @
    60 q' T) d- s" x+ Z9 D" M
    套接字(Socket)
    ( l7 k$ R0 b) O" D% a, L套接字不僅支持本地進(jìn)程間通信,還可以用于網(wǎng)絡(luò)通信。
    2 [* W! T/ f0 A7 B, C* s7 l
    , W2 {+ Y* _8 _$ a基于套接字的 IPC 支持雙向通信,比較靈活,適合嵌入式系統(tǒng)中進(jìn)程之間需要頻繁且復(fù)雜的數(shù)據(jù)交互的情況。0 U5 M; |) O3 p+ S

    ' y. E/ j- a3 A- Y, R6 Y示例! g3 e& z9 @. z

    . e4 L( Z5 s  h4 n
  • int main() {    int sv[2];    socketpair(AF_UNIX, SOCK_STREAM, 0, sv);# V! g3 k' r1 h) C
        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
    + {" L. ~# X$ g5 m+ y$ b+ s8 O", buffer);        close(sv[0]);    }    return 0;}7 ?1 x. ~7 }  [6 K- ]9 \0 |
    7  [" o8 x2 U/ R
    信號(hào)(Signal)
    ' _: [4 K4 U$ H5 h1 X8 V( q$ o3 Q信號(hào)是用來(lái)通知進(jìn)程發(fā)生某種事件的機(jī)制。進(jìn)程可以捕獲、忽略或處理信號(hào),典型的信號(hào)包括 SIGINT(中斷信號(hào))和 SIGKILL(殺死進(jìn)程信號(hào))。
    ) ~/ L' g) l. x+ @! V" W
    ) Y5 ^$ m- D1 P# ]2 P" E示例:處理 SIGINT 信號(hào)(Ctrl+C)。
    ( R4 W" _3 J- L4 T1 D
    0 V( S8 Z8 {6 a! B$ h0 R7 E. P
  • void sigint_handler(int sig) {    printf("Caught signal %d1 Z( |, q* k% E
    ", sig);}' c  f+ a- C% \$ s
    int main() {    signal(SIGINT, sigint_handler);    while (1) {        printf("Running...
    ' H" @" c" u8 V. {2 ?");        sleep(1);    }    return 0;}
    * j3 y7 F9 V1 L  T. c; s進(jìn)程間通信的機(jī)制多種多樣,選擇合適的方式取決于應(yīng)用場(chǎng)景的需求。" r) w& U8 s1 \/ k) F

    , X7 a  h! w/ Y" z* T- C: s
    # |$ F# V7 `+ P( @" C; o2 u點(diǎn)擊閱讀原文,更精彩~
  • 發(fā)表回復(fù)

    本版積分規(guī)則


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