|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
+ N; x( J/ Y0 C9 m( @0 v: ?5 {
NAME
+ G7 v0 h$ X' b: N% a: gmq_open - 打开一个消息队列 (REALTIME)
% X Z8 d. {2 Q* O' R1 J) M
# s' w+ E; ?) W d8 K1 B. {6 g
/ |/ ^2 S: x" g1 _ uSYNOPSIS5 g6 @" E7 t& c; M1 T' n
8 v# ?) k) a/ E' l: [+ F$ i- #include <mqueue.h>
- mqd_t mq_open(const char *name, int oflag, ...)
- mqd_t mq_open(const char *name, int oflag, mode_t mode, mq_attr* attr) //O_CREAT
* a& I3 `7 u/ Q8 x
8 z0 }' b9 N* Y5 D! n0 H
3 r& R: T- J- g, n1 mDESCRIPTION' w" o# d+ [( S% ?( P5 E
- x+ X1 g- w/ t& _, c& B9 y
mq_open() 函数会通过一个消息队列描述符(类型是mqd_t)建立一个进程与一个消息队列的连接.
7 n3 u2 L; g; p. p! F& W' H3 b) F4 t% i; f* N
该函数会创建一个打开的消息队列的描述符, 其他函数就可以通过这个描述符操作消息队列.8 l( g8 M! P& m
! o; @0 h8 P! E8 |% y4 v$ a# Q
) |# e! V1 O; x- B k2 S( cPARAMETERS" i5 ]4 W: ?1 D P3 B' I2 T0 K
3 X2 c, z8 [ D+ e8 V W9 b
①name
, d$ K- ^ ]1 V' i$ x参数 name 是一个指向消息队列名称的指针. 但是名字是否出现在文件系统中,是否对其他以路径名为参数的函数可见是未定义的.5 @- p0 l( V# [5 m2 e/ p, t& X
/ ` `1 ]3 x$ x参数 name 的长度限制是由系统实现决定的(如何获取这个限制),不需要遵守路径名的限制 {PATH_MAX} 和 {NAME_MAX}./ P; ^, J/ ]$ E2 O' K4 U5 W
( J; C7 u# k6 U5 g7 }# Q9 [: N0 U如果 name 参数以"/"字符开头, 只有name没有被删除,所有使用相同name值调用mq_open函数的线程,访问的都是同一个消息队列,
- U! j n7 t+ l0 @. ?4 Q0 m. [8 ~& m! n9 g0 E" C* z
如果 name 参数不是以"/"字符开头,效果是由系统实现决定的.所以name参数一定要以"/"字符开头.
, I8 p0 P9 o" f' }8 D4 i0 G, c
& _: H F, @' N" C: e# D0 o
4 Q z8 V/ Y( p②oflag
# X- O9 c. O# Z. o% h( i. \9 N7 _7 T2 f" k7 \, ?
参数 oflag 表示想要访问(receive/send)消息队列的方式.
0 e! V L. u% S- e. C, s5 p0 [
, E! V4 P2 @. {- m参数 oflag 是由下列宏组合计算出来的, 注意必须包含前3个(访问模式) 中的一个:) l* q |& b t6 T
. i5 K( Y' \" C# L9 FO_RDONLY (只读)
/ C6 F* K" |/ m7 ?' _" _2 i" x# Q8 K, j
打开一个消息队列用来接受消息.& b' x' o+ f. c" I5 G
: n- ?0 P. [6 X+ E) u调用进程可以使用mq_open返回的描述符用于函数 mq_receive(), 但是不能用于函数 mq_send().) q- F; p8 ?9 t% d% {) ^
/ A* ~7 u6 T) W+ ]" N2 d, L
一个消息队列可以在相同或不同的进程中多次打开用来接收消息.
) o4 x) h( ]. Q7 `. {% S
; B8 w6 V6 o; A/ AO_WRONLY (只写)
$ h1 U, U# D# e- N; _+ b6 j4 N) v, K: Y- k& t5 E, p
打开一个消息队列用来发送消息.7 t5 V* `- C4 ?) l
- c7 [) b$ h; |) F: b2 `调用进程可以使用mq_open返回的描述符用于函数 mq_send(), 但是不能用于函数 mq_receive().. \7 x: x$ V0 C. ~2 N0 H& F
! p7 a# A% k% {9 t% f, G一个消息队列可以在相同或不同的进程中多次打开用来发送消息.( t2 V# Q3 X+ V! e" V
( `2 X4 g6 [8 ]
O_RDWR (读写)' ~7 F- n- z4 }) t) x9 t) @
' S8 I; ]6 V3 U; q \7 `打开一个消息队列用即可用来发送消息也可以用来接受消息.
) ?) Y8 N- A; z9 N( ]# f+ O
1 |) c& W0 W8 Z: v5 Y' a调用进程可以使用任何支持O_RDONLY 和O_WRONLY 访问模式的函数.0 T" D" g E2 X6 ~; Q" m
, u2 f- z. ?8 b x一个消息队列可以在相同或不同的进程中多次打开用来发送消息.' D4 Y4 R% r7 K) [3 {' i s7 c
) X( w. \( |! }! B/ h* G
; I5 F9 W% j# h. `/ P, u2 y8 s5 G4 ^1 X' e E
Any combination of the remaining flags may be specified in the value of oflag:* P6 E. L j8 |+ i9 s! A/ d& C
, q: w: i8 N$ o8 O3 S1 \& H
' U) M% `8 i( ~( P4 R hO_CREAT (创建)
! I$ Y9 t! x3 a( D* L6 y6 D1 l+ ^2 z0 V0 f" {
创建一个消息队列. 使用这个参数需要追加2个参数: ③mode(类型是mode_t), 和④attr(类型是mq_attr*).; T$ q4 t3 ~6 A3 i0 x
如果name参数指定的消息队列已经存在, 那么这个参数将不起任何作用, 除非像下面 O_EXCL 中提到的情况;
' Z+ G2 v5 X1 B. [否则, 会创建一个空的消息队列. 消息队列的用户ID会被设置成这个进程的实际的用户ID.
4 ~( W1 A& c0 Q5 u3 } 消息队列的组ID会被设置成这个进程的实际的组ID; 然而, 如果参数name 指向的消息队列在文件系统中可见, 那么组ID会被设置成包含消息队列的目录的组ID.* t, B' B7 M: `6 u
如果参数mode中的位与文件权限中位不同,这种情况是未定义的.
; `9 M9 D$ D9 ~" H8 n4 ]如果 attr 是 NULL, 创建的消息队列是系统实现的默认属性. 如果 attr 不是 NULL 并且调用进程对参数name指定的文件有特定的权限(什么权限),
3 k, g$ j- h0 |0 e1 M5 l那么消息队列的属性 mq_maxmsg 和 mq_msgsize 会被设置成 attr 中的属性. 属性 mq_flags 和 mq_curmsgs 会被忽略.8 l0 W, V* G N5 x5 r7 z; w" p
如果 attr 不是 NULL , 并且调用进程对参数name指定的文件没有特定的权限,函数 mq_open() 会返回失败,不会创建消息队列.
r7 I: U# Y$ D2 `
# J0 r" P( G" {4 K
) K W) F Z4 l I: t* A5 cO_EXCL (既存检查)
+ V- m7 g* g, C% H
2 Y" E5 |2 [% J- S0 n如果 O_EXCL 和O_CREAT同时被设置了, 如果消息队列应经存在,那么函数 mq_open() 会返回失败.
X, x6 T Q( o3 z# n提供了检查消息队列是否存在的方法, 如果设置了 O_EXCL 必须同时设置 O_CREAT 否则结果未定义.+ Y7 Q( {# h3 I* k0 d
% C! y, w( N+ \& D5 c! CO_NONBLOCK (非阻塞)+ Q' l8 \9 m3 R2 o1 s+ K
; x; }# [8 o4 a2 d决定函数 mq_send() 和 mq_receive() 在获取当前无法获得的资源或消息时,是一直等待(阻塞), 还是返回失败并将 errno 设置成 [EAGAIN]; * j0 J" P- s) ?7 G3 B2 Q8 G
. b) O0 S2 Y* I8 f" t
7 _8 c8 M% Q/ ^$ h) SRETURN VALUE. v- _ p; M5 s& @. U6 Z
! T% a. a6 V# K G
如果函数执行成功, 函数返回一个描述符! O! e1 {8 ^ S: }" g9 T! [9 z
0 S- G8 n4 |& C2 ]; b% M: y! l; V如果函数执行失败,函数返回 (mqd_t)-1 并且设置errno,errno的种别详见下面的ERRORS一节.
& N& ^2 x% j& b
( V* w, A @% {8 M5 H$ c 5 C! Z# H! Y9 x b
( `& `9 q" Y% t6 T$ M! s
ERRORS. U& f3 f3 t9 M. ]" @9 o
0 g5 a7 L# U, D; X# L[EACCES]) w4 s5 [& Z L4 y2 o+ h
( h. B+ A* Q+ h( I. ? F- lThe message queue exists and the permissions specified by oflag are denied, or the message queue does not exist and permission to create the message queue is denied." b, v" e* U: s8 y, ~. M
- F% }, o) G2 p' \9 @/ s3 g$ v[EEXIST]+ ]7 R" P2 m* @5 f6 ~
! ~" ?/ s& P$ G9 g" d! }/ M- s
O_CREAT and O_EXCL are set and the named message queue already exists.
6 j: v0 l: T$ D3 l& x
; \& D% p9 a# l5 ?9 ?[EINTR]
, V& T9 W$ L1 U( z: k; h" a
7 H S) F" T7 i函数 mq_open() 被信号中断.1 ]4 X$ k" x' E" W; i
. r; n% m1 ?4 L3 `. M[EINVAL]
7 D- u6 m6 d6 V. y. o. `" O; E3 i, \% \& R4 d4 |4 T
函数 mq_open() 不支持参数name指定的路径.
% x" K8 s: T6 @7 l# X: y2 o! l
, c! F0 V/ \/ {3 w" ^/ w[EINVAL]9 `# \1 I& T6 P, p
3 d/ b5 w$ Y1 v7 @, `设置了O_CREAT标志, 参数3 attr 不是NULL;并且 mq_maxmsg 或 mq_msgsize 小于等于0.# Y6 U/ j) K+ W- n ?
/ E0 b# G! H. A9 K7 w8 i
[EMFILE], {6 s2 U5 _/ y, R: r7 K6 a
% I, |9 ^) v0 W z' A2 g
本进程中使用了过多的消息队列描述符 或 文件描述符.3 U6 {8 t' V4 n) z) e z
( p* [# Z3 @0 c. t i9 A
[ENFILE]& Z. Z: q1 U& V7 Q6 S9 A1 f( w, y
# y$ [* T9 j- Z& A2 m系统中打开的消息队列数目超过了系统支持的最大数.
) i+ ~3 \- X( W: F' O
0 C+ [" A5 m0 t! Y, ]7 I! m' e[ENOENT]! \& X9 r# I; F+ R8 | R
& l3 j. v8 K: ^4 l' s! }) s
没有设置O_CREAT标志,并且指定的消息队列不存在.* r1 m6 v* A2 R4 }4 n
& L _5 b7 B) F+ q7 D' J' a
[ENOSPC]
4 \$ \% s' q! m/ M' B, H2 @0 S8 H7 M
空间不足,无法创建新的消息队列.
3 I2 V& T" N+ _4 ]( }
- E! T- j! R1 {1 \ v. _[ENAMETOOLONG]
" ?8 \$ j4 W5 ^ ?
# v9 x6 Q1 V/ X( O7 x4 k参数 name 的长度超过系统定义的最大长度.4 i; m/ E$ o. e/ ]0 j
" v% E5 x b7 ]7 T( h: r- r在不支持XSI系统中,name 的长度超过了 {_POSIX_PATH_MAX},在支持XSI系统中,name 的长度超过了 {_XOPEN_PATH_MAX};或者# |1 q& M8 z) S. y* y
( \7 x9 U9 d5 e& y& X在不支持XSI系统中,某一级路径的长度超过了 {_POSIX_NAME_MAX},在支持XSI系统中,某一级路径的长度超过了 {_XOPEN_NAME_MAX};6 y) E. }0 O& a7 K- t5 h
- z! L* a3 H7 A' t1 A8 t0 |EXAMPLES9 y# d3 Z7 x" I. Y
|
|