|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
# D3 w2 o3 K9 i0 r% h2 {' N( JNAME, B' g. p B5 @1 S j
mq_open - 打开一个消息队列 (REALTIME)
" Q% u6 Z, K I
* J7 i$ H% K* R' c
9 q- x n& \6 W9 Z/ G! pSYNOPSIS
% h$ R/ R2 U' w4 N5 h% T$ z
* _* s* i5 G. l, m% n" J0 }- #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
) I/ b- ~3 R% ] {
3 v4 G6 o% \7 r3 J8 M- t* {$ M& K9 }0 t
DESCRIPTION
; w" L" g, x9 F9 @2 J, q' m1 d$ k- A
mq_open() 函数会通过一个消息队列描述符(类型是mqd_t)建立一个进程与一个消息队列的连接.
$ J- ~7 L2 x {. s# L5 Q2 G
8 b% M2 s2 P' B- G4 R) X! q( N5 F该函数会创建一个打开的消息队列的描述符, 其他函数就可以通过这个描述符操作消息队列. ?" X3 L/ l1 G- V* d, d
3 }" k( u# S: I
4 C, t, c$ w% l0 w4 i @& r( l. ~
PARAMETERS
& J7 {: K$ ^! |
0 J. b8 {/ ^6 [5 w0 E8 [①name/ c) P; ?1 M1 U4 z4 ^' I
参数 name 是一个指向消息队列名称的指针. 但是名字是否出现在文件系统中,是否对其他以路径名为参数的函数可见是未定义的.
+ ^ x$ C0 l! K+ W
! E7 A4 N0 L2 Q o5 E" u/ T: @参数 name 的长度限制是由系统实现决定的(如何获取这个限制),不需要遵守路径名的限制 {PATH_MAX} 和 {NAME_MAX}.( S1 L4 t% A( ^, Y+ s
2 ~8 _+ G+ U% Q* v5 z
如果 name 参数以"/"字符开头, 只有name没有被删除,所有使用相同name值调用mq_open函数的线程,访问的都是同一个消息队列,
1 O6 P% K7 E. B. w) l
5 Y8 b2 `( D+ i& ~9 P l5 [1 C如果 name 参数不是以"/"字符开头,效果是由系统实现决定的.所以name参数一定要以"/"字符开头.
* B$ S3 ^- U. s1 Y7 e: q' |3 e8 _) h) i# E
0 H( D& y7 H. k. w1 x8 c6 f. X. Q5 e M
②oflag7 H* u7 C5 t: b# A, x
{( E3 \* X1 x: l, b- ?8 O
参数 oflag 表示想要访问(receive/send)消息队列的方式.
! ]( g2 i* h7 i2 J
2 h: {4 O1 ]/ M. }! L: P/ U参数 oflag 是由下列宏组合计算出来的, 注意必须包含前3个(访问模式) 中的一个:
0 R) F* \% t& L T' N) D6 }
" \; A5 d5 l8 u3 C( OO_RDONLY (只读)+ S2 q+ k& ?# r2 W
& I0 J" [/ N' g) n打开一个消息队列用来接受消息./ o5 q. B* x' B2 A& t/ V7 P
h' m1 A0 u2 _" ~" `" G4 F
调用进程可以使用mq_open返回的描述符用于函数 mq_receive(), 但是不能用于函数 mq_send().' h, g+ A6 v) u, c
+ j: u4 g1 |' c e- H' l% o
一个消息队列可以在相同或不同的进程中多次打开用来接收消息.
4 G) l1 f, U$ n" [- X( \9 m) S. c" c! A' z2 o: z
O_WRONLY (只写)
# C/ [+ d: L+ S) |) W# P4 ~+ ?7 \* T+ ^( s% \; {6 J5 Y
打开一个消息队列用来发送消息.
. X# S+ V* K+ L6 r' S
( j6 j% {6 ~( F5 v9 l( r调用进程可以使用mq_open返回的描述符用于函数 mq_send(), 但是不能用于函数 mq_receive().
C% D' ?4 l7 y& q+ ]7 T; d. `" [8 m: R" A
一个消息队列可以在相同或不同的进程中多次打开用来发送消息.7 f: a- Z0 a% [5 N$ l
0 c! _. Y3 k c4 I3 C2 s# }0 }O_RDWR (读写)
: N% }7 K! W& r; m2 s( ?: e. t$ \
打开一个消息队列用即可用来发送消息也可以用来接受消息. U# h/ N( T7 Y, {$ f" ?
" k4 I1 R. B5 w, T! P
调用进程可以使用任何支持O_RDONLY 和O_WRONLY 访问模式的函数.% k7 R- r: O6 a) w) f. W
2 U8 V5 }; a0 z- u5 s
一个消息队列可以在相同或不同的进程中多次打开用来发送消息.9 X7 H3 J1 V! g- v1 F3 D3 o8 A5 u" G
+ M5 r% P' t3 F" ^1 R, r4 s
* @6 L q7 A5 j, f
% g/ k/ ?0 `( j8 M3 b R/ a
Any combination of the remaining flags may be specified in the value of oflag:/ R v; h' H7 L& y3 p8 V
1 f! I4 @2 V$ e; j6 V% d& B( Z$ |0 K u4 y
O_CREAT (创建)
8 x4 q' f- K0 N! L, I. x3 G# I+ p6 G/ s' J
创建一个消息队列. 使用这个参数需要追加2个参数: ③mode(类型是mode_t), 和④attr(类型是mq_attr*).7 T8 A9 B8 y0 X* a d' `# o
如果name参数指定的消息队列已经存在, 那么这个参数将不起任何作用, 除非像下面 O_EXCL 中提到的情况;
j& Y: f5 H" k8 u9 Z% H否则, 会创建一个空的消息队列. 消息队列的用户ID会被设置成这个进程的实际的用户ID.
" s/ m6 L, L1 L2 M* _* T4 R# r 消息队列的组ID会被设置成这个进程的实际的组ID; 然而, 如果参数name 指向的消息队列在文件系统中可见, 那么组ID会被设置成包含消息队列的目录的组ID.# d& ]: L# p7 J! h9 ?* p
如果参数mode中的位与文件权限中位不同,这种情况是未定义的.
% n9 A" ]9 L, E ~6 c. E. |) E如果 attr 是 NULL, 创建的消息队列是系统实现的默认属性. 如果 attr 不是 NULL 并且调用进程对参数name指定的文件有特定的权限(什么权限),: s7 j* u$ p5 ]8 p9 O9 i8 P
那么消息队列的属性 mq_maxmsg 和 mq_msgsize 会被设置成 attr 中的属性. 属性 mq_flags 和 mq_curmsgs 会被忽略." e) B& Z+ A: x# ^! A! k/ e
如果 attr 不是 NULL , 并且调用进程对参数name指定的文件没有特定的权限,函数 mq_open() 会返回失败,不会创建消息队列.
. t Q* Q/ n2 A; j& t( v! r4 M, L3 Q
1 C; P1 R0 u9 i% x, h$ V* l
O_EXCL (既存检查)& p' m, X2 D6 M
; D& ^; D( Z$ P6 G2 t
如果 O_EXCL 和O_CREAT同时被设置了, 如果消息队列应经存在,那么函数 mq_open() 会返回失败.
: c. q5 [' Y3 j" W9 J% F" u提供了检查消息队列是否存在的方法, 如果设置了 O_EXCL 必须同时设置 O_CREAT 否则结果未定义.4 A4 P0 {/ N8 q+ C9 i
& W' u# @. s+ m$ }- k7 @* NO_NONBLOCK (非阻塞) r2 v( \ a. `# O7 L3 j* {
; C/ z5 m- l. z! ~$ c/ X
决定函数 mq_send() 和 mq_receive() 在获取当前无法获得的资源或消息时,是一直等待(阻塞), 还是返回失败并将 errno 设置成 [EAGAIN];
' x8 ~9 X% g% l: Z
- R0 V5 T4 ^6 B# S6 }% W4 Z/ H3 ?: R/ c" }/ ^
RETURN VALUE
, @) e8 p( F2 A0 `' J1 O( H$ J% y9 }- X" F! ~9 y- ^% |. p- q
如果函数执行成功, 函数返回一个描述符
' W% Z9 y, B s) G/ [$ w: E! s; h7 x4 ?3 e; Y+ p
如果函数执行失败,函数返回 (mqd_t)-1 并且设置errno,errno的种别详见下面的ERRORS一节.& |1 a% Z0 }' Z5 m
$ g# _1 Z* B; A
! q1 P p7 l9 V3 l& W3 ?' @! G
' N3 _& _' k# k' }$ q/ D( W' @ERRORS7 r- ]2 d- ?8 E8 l( z
# b0 P J5 e( E9 M: r( V4 L# ^. U& P[EACCES]) J' q4 m0 L! q) D: K3 t9 R4 w8 v. h
: X# V* o0 N, X# ]$ ~ N% s
The 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. N* `1 a. @8 |$ O' b
& F9 w3 _! g6 g1 _[EEXIST]
% Y% K1 q" f9 @: _8 F6 k" K
) P v" a* {5 b9 OO_CREAT and O_EXCL are set and the named message queue already exists.
v4 b' O/ U9 U
3 j; n! C1 F+ L[EINTR]
% W' s0 G9 I8 G" }
# r7 U, W/ |4 D0 z( ~函数 mq_open() 被信号中断., a, {, C3 C; m$ B- i
4 I! D& U8 ?9 [. j4 c3 Z, C% @. d
[EINVAL]6 g; F- f7 Z( }; W
7 F) k" Y1 P) l3 A1 z* |函数 mq_open() 不支持参数name指定的路径.& e9 y" x6 z* v! \7 m
% B: U h* t! [6 L- q/ k
[EINVAL]
+ t9 _3 B1 I: V t: B' I0 Q3 ~* E3 d
设置了O_CREAT标志, 参数3 attr 不是NULL;并且 mq_maxmsg 或 mq_msgsize 小于等于0. o( [9 t# ~& N" n& h- i* d7 r0 u
! } o4 |% X& C7 t! q/ ~" R; M2 b, _
[EMFILE]
+ K* K3 Z% l+ n# x. h: ]' t+ Q) q& Q# Q6 u; @/ I
本进程中使用了过多的消息队列描述符 或 文件描述符.3 k3 S- v/ b( }1 _3 A$ h
6 S8 E$ z6 n% j3 c+ v0 w! B8 b[ENFILE]' |4 _; p9 t& _% _; C( R1 Z6 K* H
2 x$ d$ ?$ g# U6 y. x7 S% R系统中打开的消息队列数目超过了系统支持的最大数.
4 J- g9 G/ Z; {3 c( K# |' p( J+ g) g
[ENOENT]0 u7 x! ~1 e6 A9 W+ f' u
1 L2 l n/ [9 i- o
没有设置O_CREAT标志,并且指定的消息队列不存在.: |* Q$ ]) T) q1 l$ Y& c% B2 i
% o) I' d6 |. [6 k
[ENOSPC]. p2 y& A9 e, L: H! i
/ ^% o* i! E3 ^空间不足,无法创建新的消息队列.5 N. }* J/ |" w3 |7 {3 B4 S
1 l. z2 ?: u- y. J9 a) c[ENAMETOOLONG], v& f7 ~( ~2 x9 O3 ?
& R0 e+ e# |* V; F% u8 I, X参数 name 的长度超过系统定义的最大长度.
# ?( z/ h* ^2 u1 W6 @
. a& U- R# J- l p' n6 C' X: P在不支持XSI系统中,name 的长度超过了 {_POSIX_PATH_MAX},在支持XSI系统中,name 的长度超过了 {_XOPEN_PATH_MAX};或者& B3 Z3 y% J8 F. y
0 z# C% g7 F' C1 U& j4 [1 c; J% d
在不支持XSI系统中,某一级路径的长度超过了 {_POSIX_NAME_MAX},在支持XSI系统中,某一级路径的长度超过了 {_XOPEN_NAME_MAX};: C* Z% p( Z a
: a! T. H2 {) F9 e% fEXAMPLES
) O; E+ m9 c3 Y5 n& i! j. N |
|