标题: Linux进程——消息队列 [打印本页] 作者: mytomorrow 时间: 2020-4-3 10:17 标题: Linux进程——消息队列 ( r- B+ ?$ o- c" b) C/ F
消息队列是消息的链接表,包括Posix消息队列system V消息队列。消息队列用于运行于同一台机器上的进程间通信,它 ; N) J. G2 F6 j和管道很相似,有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。消息队列克服了 ' W6 I+ R9 W7 M/ E2 {- y6 \信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺点。 我们可以用流管道或者套接口的方式来取代它。 3 i( Q( d$ I1 X- A' I U3 A \/ t$ p" [ t
查询系统消息队列:ipcs -q 9 V7 R- U8 o+ V) H: A. U2 d0 d( W0 m9 M- i
#include <sys/types.h> ) A, o- y& U" D f* W ! y& z; A" h' A3 Q1 t#include <sys/ipc.h>! z, Q5 P3 @6 i$ o
% `7 g; E: C# x/ O5 `% [5 y8 J
#include <sys/msg.h> & H5 G. h- z* [3 _6 ^2 D 7 _- W( n5 |& ^/ K% e7 Oint msgctl(int msqid, int cmd, struct msqid_ds *buf);2 j! ^/ P7 r& M( U( t6 N, M
! Q$ p8 v9 t3 o4 V. H5 ]int msgget(key_t key, int msgflg);; t; {4 c! @/ j& l# J# S% m) v
a0 M& R& Q* q$ v: G
int msgrcv(int msqid, void *msg_ptr, size_t msg_sz, long int msgtype, int msgflg); , C8 v, w) }/ T0 H4 f! O2 a6 W: B
int msgsnd(int msqid, const void *msg_ptr, size_t msg_sz, int msgflg);! K( O3 M# s. e$ u b. _- c% K
% ]6 s% b. f& W7 w5 z$ Q
" v7 W7 ?' u8 C5 D" b ) R% |; v) H" V0 D* |7 V3 qC代码 + b+ w% z% k0 M) I: e, g$ q- N/*msgserver.c*/ " G* [/ y% d4 ^$ l
- i) {( j0 N& J
#include <stdlib.h> - E1 d, w$ X) m) R4 ^2 M
#include <string.h> & J8 j4 H& a9 ~% K#include <errno.h> 8 Z% [# W5 x/ y- @
#include <sys/types.h> ' d& ~9 t+ j) N#include <sys/ipc.h> 9 r$ C Z, v. {$ q5 j0 T
#include <sys/msg.h> 1 T% s: |! l/ g* O0 R7 J/ {: L#include <sys/stat.h> 3 b8 [4 x) {9 y% I- j! B - N4 s I: R8 T#define MSG_FILE "msgserver.c" W- [( F" p6 [$ p k#define BUFFER 255 : M) c9 C/ M. V
#define PERM S_IRUSR|S_IWUSR + Y0 A, O/ k! M( D0 t4 D, D/* 服务端创建的消息队列最后没有删除,我们要使用ipcrm命令来删除的 */ ' N8 C- J- X1 U$ b9 v1 i/* ipcrm -q <msqid> */ ! _3 E* ~0 Q4 _' b , m1 f, N- ^' L( M2 G2 jstruct msgtype ' W' [8 s# O. i
{ " k9 ]2 e/ H- O4 `- H6 q" \ long mtype; + C- F4 o0 _0 |, p9 Z2 |
char buffer[BUFFER+1]; & g8 ]2 F/ o3 Q4 Z( h, s$ s9 m
}; 3 K/ d0 L# ~' g7 D m6 x2 B1 }# ~5 f5 h' b% e, aint main() ; |0 `1 n* S: A$ h
{ ( @) k& `- H+ M
struct msgtype msg; + x* s$ A G- s. k; m9 e( k* P4 Z
key_t key; " H) v4 d1 S0 ~% b) a int msgid; $ o$ Z! {% n T- i ) _, O/ T% [& a# J. U if((key=ftok(MSG_FILE,'a'))==-1) * m/ X7 `# T0 S* a. W; X
{ . z! L+ `- }9 @; G$ \. c& y
fprintf(stderr,"Creat Key Error:%s\n", strerror(errno)); + s# e4 ^) J/ x, n8 {* r, X
exit(1); ) `! \. ~3 ^- U, U5 p } : S1 k5 _! w6 i
" ^, F& V A# F1 E0 N, U, I3 n, d if((msgid=msgget(key, PERM|IPC_CREAT|IPC_EXCL))==-1) # x" k5 B8 X( L5 N; Y9 i
{ 2 z! C: G5 v- J2 e1 e fprintf(stderr, "Creat Message Error:%s\n", strerror(errno)); " F+ R2 O+ k8 A7 C) G6 f8 }
exit(1); 0 x# k0 r% Z1 L
} : [* F n' L: P" Y3 {- n/ x
printf("msqid = %d\n", msgid); 3 c8 A. U" q8 \( } while(1) ; I4 v! |0 {2 c: F
{ - G2 O9 r. _( ?* G) U. N+ N9 p
msgrcv(msgid, &msg, sizeof(struct msgtype), 1, 0); - R+ M4 l' Y. t1 D3 d fprintf(stderr,"Server Receive:%s\n", msg.buffer); 9 J2 ] e+ U( Q% M1 e1 z msg.mtype = 2; / O2 P1 M* [- A$ [5 \0 Q msgsnd(msgid, &msg, sizeof(struct msgtype), 0); 3 H8 \" E/ [# K3 w, H } $ c1 b5 C1 y$ c exit(0); ; |# k9 [* @) ~- u' c} 6 @ |$ p! G$ a/ p! d1 H( jC代码) {9 P' d' y$ Y3 o0 F8 x, u
/* msgclient.c */ ( e: F$ x. f; l E
1 u q, g) k) A, r#include <stdio.h> / X6 A6 g, f/ T. b f$ h1 ~#include <stdlib.h> 0 }. @, P& D8 r& S0 z
#include <string.h> % l2 W$ w, R6 |+ P* M
#include <errno.h> - H8 K" y" x( w- y8 |; P1 m% k
#include <sys/types.h> 0 X! R& \0 D! [/ j3 c
#include <sys/ipc.h> % Z, S9 C+ ]& N( b: d#include <sys/msg.h> 6 V3 Y" U r6 ^+ `5 \% j6 s5 C4 G#include <sys/stat.h> 4 T% q. h+ O5 n, t
. l- `; y" [7 i5 ]
#define MSG_FILE "msgserver.c" 4 l% T; b$ Z/ Q O3 o#define BUFFER 255 0 D4 I8 X9 G' o B$ P- P% O#define PERM S_IRUSR|S_IWUSR ; d. v, t6 n, ^9 A( N; D7 P! I; \9 [
7 s' M: S3 ~* R- b6 j
struct msgtype { ; @- E! \; j) z% X( o% B
long mtype; " i S' S% M5 V6 _ char buffer[BUFFER+1]; , g9 D8 u2 I A @$ N}; : v! ^! e9 k: d( ?# C$ l4 I
3 ]$ X# Y/ ^$ U* w+ w; ^5 R
int main(int argc, char **argv) % m. C! D7 H0 w/ Y a{ 1 T5 m" W- H' v, U/ R struct msgtype msg; + L# f6 Y/ v2 ?, U" E4 W* H4 I8 e
key_t key; ( {9 `4 C$ H; ~6 r int msgid; ' Y& C; R' `1 q+ ]% M& B ( T. u: Z: y6 f- M+ o; f0 A( w if(argc != 2) # H. Y# _/ G8 l/ b8 u
{ $ C' M4 z. ?" z: t2 q2 [$ C fprintf(stderr,"Usage:%s string\n", argv[0]); 0 } |- l% G% S T* V7 t( E: {1 I% M- c exit(1); 1 c& d f4 s$ x& {. Q# x* R5 _* u! O } % E" |( l$ C7 Y5 e ! e# U% N, p L; J* ]1 \
if((key=ftok(MSG_FILE,'a'))==-1) ) r7 y# K7 L( _2 I% `! o9 t+ q( ] { ! M1 i. t4 v& b# f& { fprintf(stderr,"Creat Key Error:%s\n", strerror(errno)); 8 G P1 A+ t# s0 T) T+ C8 c* W exit(1); / r# V, i1 B1 k! q; w# c
} , [0 g" l8 j+ U7 Q: C7 n* v
- d1 \ @8 A: ?2 F$ I/ _, O
if((msgid=msgget(key, PERM))==-1) " B3 M) X4 P$ j# ?
{ ! b5 H; j- q! n$ B9 C fprintf(stderr,"Creat Message Error:%s\n", strerror(errno)); 2 ?. D, @. j# x B: I$ P/ b exit(1); 9 D6 c8 x4 m& G" f
} $ x0 ^) }8 u9 R' e$ b" { $ Z7 L* P' | L9 H: T! O6 G
msg.mtype = 1; / m" ]& J( g2 N! ?4 P; L% r
strncpy(msg.buffer, argv[1], BUFFER); 3 m B( J1 u. j9 F9 ]4 w msgsnd(msgid, &msg, sizeof(struct msgtype), 0); . W' I* ?1 h( b6 z
memset(&msg, '\0', sizeof(struct msgtype)); / d3 H- } H* i% L
msgrcv(msgid, &msg, sizeof(struct msgtype), 2, 0); % Q; N1 g3 o1 M$ M8 P7 h* ? fprintf(stderr, "Client receive:%s\n", msg.buffer); 0 p& p5 \4 u) q. H, [. n" H exit(0); 7 v; y6 S7 |/ H) W; y- s7 [} 作者: CCxiaom 时间: 2020-4-3 18:25
Linux进程——消息队列