|
3rqolratvad64088525943.gif (60.41 KB, 下載次數(shù): 0)
下載附件
保存到相冊(cè)
3rqolratvad64088525943.gif
2024-12-10 21:53 上傳
) 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
bsbbcgpudkr64088526043.png (106.85 KB, 下載次數(shù): 0)
下載附件
保存到相冊(cè)
bsbbcgpudkr64088526043.png
2024-12-10 21:53 上傳
. 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% Wstruct 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 ~, Gint 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 nint 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. Pvoid 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
pxe3tci4tfg64088526143.jpg (71.14 KB, 下載次數(shù): 0)
下載附件
保存到相冊(cè)
pxe3tci4tfg64088526143.jpg
2024-12-10 21:53 上傳
, X7 a h! w/ Y" z* T- C: s
qjqlous0j2064088526243.gif (45.46 KB, 下載次數(shù): 0)
下載附件
保存到相冊(cè)
qjqlous0j2064088526243.gif
2024-12-10 21:53 上傳
# |$ F# V7 `+ P( @" C; o2 u點(diǎn)擊閱讀原文,更精彩~ |
|