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

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

搜索
查看: 65|回復(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$ \! f1 D; }" x5 k
點(diǎn)擊上方藍(lán)色字體,關(guān)注我們
& |  i3 ~# h. l6 k+ D# i! y! |3 T( _$ q! X! s5 O! Z6 h5 L8 H8 ^
1.1、UNIX IPC
' Q" z% }- q: S# NUNIX 傳統(tǒng)的 IPC 機(jī)制包括管道、FIFO 和信號(hào),這些機(jī)制最早由 UNIX 系統(tǒng)引入,適用于簡(jiǎn)單的單機(jī)進(jìn)程間通信。$ m  ?2 d3 O: v6 H) a5 K% S
  • 管道(Pipe)$ Z" `# Q1 E" p5 m+ D! C
    一種單向、半雙工的通信機(jī)制,通常用于父子進(jìn)程間的數(shù)據(jù)傳遞。+ p7 z8 w) T: l! u- z  v
    父進(jìn)程可以寫入數(shù)據(jù),子進(jìn)程可以讀取。
  • FIFO(命名管道)5 G& j  y0 u" D- A6 _7 w. ]# G
    類似于管道,但通過文件系統(tǒng)實(shí)現(xiàn),任何進(jìn)程都可以通過路徑訪問該管道,實(shí)現(xiàn)雙向通信。
  • 信號(hào)(Signal)) l! Z+ T# P8 f$ N6 ~9 z
    信號(hào)是一種用于進(jìn)程間異步通知的機(jī)制,可以用于進(jìn)程之間的簡(jiǎn)單通信或事件通知,例如 SIGINT(Ctrl+C 發(fā)送的中斷信號(hào))。
    , v: a* Y! [  v8 X( |

    ; S% W; M9 ?* Z2 z9 d7 o1.2、System V IPC
    / J8 h0 ]1 ]1 \- h7 r- K5 y0 F) `System V IPC 是 UNIX 的增強(qiáng)版本,主要包括信號(hào)量、消息隊(duì)列和共享內(nèi)存,適合需要更復(fù)雜的進(jìn)程同步與數(shù)據(jù)共享的場(chǎng)景。
    0 ?9 v! ~2 q( e% e, J8 Y
  • 信號(hào)量(Semaphore)
    * d' D9 C  ~4 H( N/ A. p# Y用于進(jìn)程間的同步,通常用于控制對(duì)共享資源的訪問。) m2 ?8 C& S) Q2 b
    信號(hào)量用于防止多個(gè)進(jìn)程同時(shí)訪問同一資源,避免資源爭(zhēng)用問題。
  • 消息隊(duì)列(Message Queue)- \; s0 {8 r, E9 q; L5 v
    允許進(jìn)程以消息的形式發(fā)送和接收數(shù)據(jù)。
    * J8 ]: _) T$ i2 q/ j消息隊(duì)列是一種先進(jìn)先出(FIFO)的結(jié)構(gòu),支持不同類型的消息,使得進(jìn)程可以基于消息類型進(jìn)行處理。
  • 共享內(nèi)存(Shared Memory)
    * J: z0 m! ]+ _1 v% |( z進(jìn)程之間共享同一塊內(nèi)存區(qū)域,允許它們直接讀寫數(shù)據(jù)。6 ~8 Y- R: \: Q
    這是最有效的 IPC 方式,因?yàn)閿?shù)據(jù)不需要在進(jìn)程之間復(fù)制。: x. ?; B- ?, a$ d* B1 x7 Q% H+ o; r
      j' E! e6 y1 V
    1.3、POSIX IPC. J" R4 {  h$ x4 d) `# f% ?# Y9 d
    POSIX IPC 是 System V IPC 的改進(jìn)版本,旨在解決 System V IPC 在靈活性和可移植性上的一些不足。
      J3 b, K) O. A
    6 R. T6 P/ e/ p6 x: oPOSIX 標(biāo)準(zhǔn)為 UNIX 系統(tǒng)間的兼容性提供了統(tǒng)一的接口,使得程序可以更方便地在不同的 UNIX 系統(tǒng)間移植。6 B6 b5 d) D5 Q# _) h
  • POSIX 信號(hào)量% R9 l& M* b$ W; R. b- g1 K2 D
    與 System V 信號(hào)量類似,用于進(jìn)程同步,但提供了更靈活的接口和更強(qiáng)的實(shí)時(shí)性支持。
  • POSIX 消息隊(duì)列: n  E$ t) o1 u4 L
    改進(jìn)了 System V 消息隊(duì)列,允許指定消息的優(yōu)先級(jí),并提供更簡(jiǎn)單的接口。
  • POSIX 共享內(nèi)存& i1 o: g8 N: Z7 n6 b. E; k! X
    與 System V 共享內(nèi)存類似,但具有更好的兼容性和可移植性,接口設(shè)計(jì)更加現(xiàn)代化。
    . l. V6 g" ^" [+ b. t4 I, u

    / i; ~. i, `6 q2 \$ R# O* Q: Y# y1.4、套接字(Socket)通信& Q6 \& u2 O9 q1 G( U# h
    套接字是一種既可以用于本地進(jìn)程間通信,也可以用于網(wǎng)絡(luò)通信的機(jī)制,支持雙向數(shù)據(jù)傳輸。
    6 {0 B0 y9 v& E1 R0 \4 Z! c. C
    % T8 r" G0 B! U. g基于套接字的 IPC 可以實(shí)現(xiàn)非常靈活的通信模式,例如客戶端-服務(wù)器架構(gòu),適合在多臺(tái)計(jì)算機(jī)之間傳遞數(shù)據(jù)。
    6 \( }2 m+ O/ I9 v9 z1 _- Y' G2 L4 `, D
    各類 IPC 機(jī)制的對(duì)比和應(yīng)用場(chǎng)景:" r. M/ r3 N; q3 z
    0 l9 W, w: E+ C7 d! Z, g; ~; ]7 b& H
    ' {: A" S$ J4 g3 w# B6 J/ t' D

    . Q0 J) n) U' f2
    : s+ D& \# F* b/ v管道(Pipe)4 G: T* s0 B1 k9 I% V) @  i+ }+ S3 `
    管道是一種半雙工(單向)的通信方式,通常用于父子進(jìn)程之間的通信。一個(gè)進(jìn)程可以向管道寫入數(shù)據(jù),另一個(gè)進(jìn)程從管道讀取數(shù)據(jù)。' T5 N3 o. u5 y+ F  ~6 J- `

    4 [1 |$ D. d& g$ j& QLinux 提供了無名管道和命名管道兩種類型。
    ; X# s' M7 F: t
  • 無名管道(Anonymous Pipe)
    6 N9 ~% B: s; o' i7 G只能在具有親緣關(guān)系的進(jìn)程間使用,比如父進(jìn)程和子進(jìn)程。
  • 命名管道(Named Pipe 或 FIFO)$ u2 C, l+ O  g' C
    通過文件系統(tǒng)中的路徑來創(chuàng)建,任意進(jìn)程都可以訪問。. G# V- h! g4 q6 @8 V6 K7 l

    % F# W1 Y% T& F& \5 [; f3 M
    . T' N3 Q2 G7 M7 Z3 l, W/ h
    示例) K0 v# f0 }8 _# D# w" u/ L6 R

    $ a7 V! ~, K/ A$ K% p' y3 S  p& n% e
  • int main() {    int fd[2];    pipe(fd); // 創(chuàng)建無名管道, V7 K; v) _% k
        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" Y2 C& m- o; K
    ", buffer);        close(fd[0]);    }    return 0;}
    + y1 a  {7 d& g! y. H/ c8 Q7 w3
    9 r5 ?) @5 B% ^消息隊(duì)列(Message Queue)
    ! G, j. t5 ]! D/ E- y3 s3 _消息隊(duì)列是一種先進(jìn)先出的隊(duì)列,允許進(jìn)程以消息的形式發(fā)送和接收數(shù)據(jù)。
    : `2 z9 G! H6 j3 m& L8 b$ c3 o6 L7 i! x6 w
    消息隊(duì)列可以支持多種類型的消息,通過消息類型實(shí)現(xiàn)多種目的的通信。
    & M1 m! R; W' l5 U" v; D
    7 A4 y  d6 _# v4 t+ B示例:進(jìn)程A可以向隊(duì)列發(fā)送一個(gè)帶有特定類型的消息,而進(jìn)程B可以根據(jù)消息類型進(jìn)行處理。
    5 ]: a. p) a+ n# Q6 T/ ?
    # f) ]  V; F% B3 `" c# A
  • struct msgbuf {    long mtype;    char mtext[100];};1 a& X4 l8 z2 J; y9 q  G- ?: g
    int main() {    key_t key = ftok("msgqueue", 65);    int msgid = msgget(key, 0666 | IPC_CREAT);    struct msgbuf message;" P( ~' }/ C, P* [7 l' s
        message.mtype = 1; // 消息類型    snprintf(message.mtext, sizeof(message.mtext), "Hello Message Queue");    msgsnd(msgid, &message, sizeof(message.mtext), 0);
    ! v% }( |* Z, J! E/ l    return 0;}' ?2 q8 q3 s1 I! y- u
    4" Q1 W" s5 K( P" p" l/ ?% H) X
    共享內(nèi)存(Shared Memory). n0 L5 y% E6 U0 T# S6 y# @
    共享內(nèi)存是最快的 IPC 機(jī)制之一,因?yàn)檫M(jìn)程之間直接訪問同一塊內(nèi)存區(qū)域,而不需要拷貝數(shù)據(jù)。; t9 ]- ~" ?9 S9 |' ]$ [9 @2 `

    % `& v4 s. K% ^8 @% J8 {! n6 n( C通常使用 shmget()、shmat() 和 shmdt() 函數(shù)進(jìn)行共享內(nèi)存的創(chuàng)建和訪問。
    ; k3 W/ e- I1 c' {4 X! z" `) Z% M! d1 s! S6 O$ ^8 r& u/ b: ^
    示例* v: s9 b$ ^7 ?5 j" Y# q. f
    6 H( i* s/ E5 z6 u5 H/ i1 j8 P
  • int main() {    key_t key = ftok("shmfile",65);    int shmid = shmget(key, 1024, 0666|IPC_CREAT);    char *str = (char*) shmat(shmid, (void*)0, 0);3 H" h8 ^, o5 t+ S1 W, ?4 c
        strcpy(str, "Hello Shared Memory");
    + h% I2 ]$ _0 h5 Z    printf("Data written in memory: %s
    * b2 J5 {0 N' X0 z", str);    shmdt(str);$ ?+ u9 [1 L1 `8 J; E
        return 0;}
    9 C: i7 W/ {6 X' `0 y7 s0 `5$ p4 t( Y  I4 C* H, D- C
    信號(hào)量(Semaphore); H3 D. J& A2 z5 Q
    信號(hào)量是一種用于進(jìn)程同步的機(jī)制,通常用于控制多個(gè)進(jìn)程對(duì)共享資源的訪問。
    6 n4 I4 i9 a  N9 |, v
    2 s$ _, _4 l& R! p* @7 j嵌入式系統(tǒng)中,信號(hào)量通常用來避免多個(gè)進(jìn)程同時(shí)訪問同一資源,防止數(shù)據(jù)競(jìng)爭(zhēng)。
    7 e' q) O% ^5 _/ O* s
    7 D0 {2 @+ Y! t8 u; g1 S示例:信號(hào)量可以通過 semget() 和 semop() 函數(shù)來操作,用于鎖定或解鎖資源。6 T3 f3 H4 V3 F1 E
    $ N' @+ v8 R' W7 {0 J$ O% t% a
  • 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操作1 p: X: m9 J. s5 V! ~* X2 }
        semop(semid, &sem_lock, 1); // 上鎖    printf("Critical section; Z* ~/ R, G- S. e6 x
    ");    semop(semid, &sem_unlock, 1); // 解鎖
    4 v* r. V" s" }    return 0;}  m0 }; q' }: v
    6' S- B* {! L8 G
    套接字(Socket)
    ) r2 l+ n0 i+ t: U" U套接字不僅支持本地進(jìn)程間通信,還可以用于網(wǎng)絡(luò)通信。
    ' r4 w4 {/ [, N6 n4 J! u1 i' d) z8 ~+ k- M
    基于套接字的 IPC 支持雙向通信,比較靈活,適合嵌入式系統(tǒng)中進(jìn)程之間需要頻繁且復(fù)雜的數(shù)據(jù)交互的情況。- v$ D% x7 ^: C

    3 e" b# B# y" O$ @* Z5 a示例" e* K9 V3 {6 n

    % L/ D$ p& b) Z. p0 z# v) H
  • int main() {    int sv[2];    socketpair(AF_UNIX, SOCK_STREAM, 0, sv);
    % o+ ]1 V  R- z& F3 @    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: %s8 \" Q" Q: x: Q
    ", buffer);        close(sv[0]);    }    return 0;}
    0 e6 o2 F! {; V$ |* |7
    3 L8 C! e1 d% R' a* P信號(hào)(Signal)1 v% r3 L5 Z+ _4 w* b! _
    信號(hào)是用來通知進(jìn)程發(fā)生某種事件的機(jī)制。進(jìn)程可以捕獲、忽略或處理信號(hào),典型的信號(hào)包括 SIGINT(中斷信號(hào))和 SIGKILL(殺死進(jìn)程信號(hào))。
    4 b1 B, z3 R" {: y4 _
    2 Y) q2 f3 V/ t, }6 A: Y+ {3 ?示例:處理 SIGINT 信號(hào)(Ctrl+C)。
    " s% a+ W4 M8 }, n7 H& x& M- K. m6 r1 g. |
  • void sigint_handler(int sig) {    printf("Caught signal %d( |" r1 u4 P+ a7 `" o! d
    ", sig);}: s5 E+ u* ], X, _2 ^: ?
    int main() {    signal(SIGINT, sigint_handler);    while (1) {        printf("Running...
    % O% ~7 Z8 O* v# R/ K");        sleep(1);    }    return 0;}0 Y% W: F$ s! a; h0 |: z
    進(jìn)程間通信的機(jī)制多種多樣,選擇合適的方式取決于應(yīng)用場(chǎng)景的需求。
    : L% k. U" Y) L+ \0 h( I ; _6 f3 ~, G' j6 U% @6 O. J  X
    & A( B7 T; U7 i6 D
    點(diǎn)擊閱讀原文,更精彩~
  • 發(fā)表回復(fù)

    本版積分規(guī)則


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