|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
# p' e. V2 P( @$ n x
NAME
4 q' Z( Y/ m0 W. P9 B6 smq_open - 打开一个消息队列 (REALTIME)+ u0 g! P3 J2 h
& P9 T+ _* D( z5 | a
) D! A5 ^6 n7 s* T2 tSYNOPSIS4 }/ p% _+ V0 [' ]0 W
2 j$ K8 e. s1 u% l: 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/ u5 W6 v/ e. N+ i1 W& Q
! T- n3 o4 q/ O7 `- K: n2 A( O0 Q* g) C% d8 X1 ?5 X
DESCRIPTION% Y% [/ Q$ D. o; k8 `
3 B% z5 C6 b/ b/ j! d2 j! Y& }
mq_open() 函数会通过一个消息队列描述符(类型是mqd_t)建立一个进程与一个消息队列的连接.
& x1 s4 c' L+ b
B" i4 { @3 `- Q$ d该函数会创建一个打开的消息队列的描述符, 其他函数就可以通过这个描述符操作消息队列.
$ O1 C5 D* b7 R) Y
. Y) _+ B, ~$ l5 b: A% y
0 o: j1 j% {8 o% bPARAMETERS6 Y a1 {' H: k0 p4 T9 V8 @* p7 I1 ^
: ]( j; C3 l. l( k {$ ^7 e2 S①name P* D% U/ v3 Q' h
参数 name 是一个指向消息队列名称的指针. 但是名字是否出现在文件系统中,是否对其他以路径名为参数的函数可见是未定义的.; O: z" B1 a) [$ f. A
7 ~# M$ L, }5 C1 Y" z) M参数 name 的长度限制是由系统实现决定的(如何获取这个限制),不需要遵守路径名的限制 {PATH_MAX} 和 {NAME_MAX}.* c0 G4 k2 ^0 b( _5 w; v2 C4 u0 Y h
, j" A/ |) u1 j4 a
如果 name 参数以"/"字符开头, 只有name没有被删除,所有使用相同name值调用mq_open函数的线程,访问的都是同一个消息队列,
, [7 n' @0 Z6 I. D8 K
; O3 W7 n! f$ o) l如果 name 参数不是以"/"字符开头,效果是由系统实现决定的.所以name参数一定要以"/"字符开头.; c# T+ \" G' O& S7 T/ l
+ E# M* H, v5 S9 o- u* X
& N4 q/ z4 e& A4 C②oflag4 w" t2 D, z! |4 y4 ?
9 Z) ^4 |6 @- Q" f" p0 Y参数 oflag 表示想要访问(receive/send)消息队列的方式./ E8 S; M5 ^" P% _( i
5 O3 H! H1 @" l; G. g! C0 n参数 oflag 是由下列宏组合计算出来的, 注意必须包含前3个(访问模式) 中的一个:" G0 i- H& I- `4 W h5 K
; k C8 j+ W1 { K Z* L2 n, I. o
O_RDONLY (只读), H$ _$ q( E R
/ ?/ u2 i) F" A, O打开一个消息队列用来接受消息.
" ], u: G8 r/ ]2 ]- K& ]+ h7 M0 d7 x" s1 h' O' i0 ?7 g8 W* T
调用进程可以使用mq_open返回的描述符用于函数 mq_receive(), 但是不能用于函数 mq_send().' a8 @* S3 k @& S, N& R
# W1 _+ \& q" O$ p
一个消息队列可以在相同或不同的进程中多次打开用来接收消息.* U" |! l* Z* M) p& s2 I
+ y8 D+ m! J+ Y2 q9 K( |* ^
O_WRONLY (只写)
( a0 R/ A/ O. L3 B
6 |8 r& X. `8 \8 {0 O& Y; \打开一个消息队列用来发送消息.
+ Z6 d* V+ u, D5 {2 Y6 D# w- Q
5 G2 u+ N5 |$ K0 |; B( m# f& U调用进程可以使用mq_open返回的描述符用于函数 mq_send(), 但是不能用于函数 mq_receive().
0 Q$ V4 K/ P( l' U/ m
# K* r, @, H" ]% @+ M$ p一个消息队列可以在相同或不同的进程中多次打开用来发送消息.
5 d g8 `1 ~( z# M: z3 V6 `% q8 ^2 G0 Q9 p: r
O_RDWR (读写)
8 p4 G( B! P) i* H- `' q- S7 s* i
2 i# j; t# y- \+ x' {打开一个消息队列用即可用来发送消息也可以用来接受消息.
" g; G% \1 i% L" u* B! C2 Y* y' x3 B% I: I
调用进程可以使用任何支持O_RDONLY 和O_WRONLY 访问模式的函数.
7 o5 s1 ^4 n: o( J
1 H3 @; z' R% F一个消息队列可以在相同或不同的进程中多次打开用来发送消息.; L- r! D8 B- j8 j, G6 q# o2 X
# [+ N" j4 y( L; N! _ 8 n5 R V# y. K! R9 P/ K. y# g, N
0 i- b8 u6 h# G8 xAny combination of the remaining flags may be specified in the value of oflag:) @1 C6 V$ `4 @: I! S% J5 g* ?1 ^, _
5 T0 g- R9 g5 S# y5 d( {" z
9 _2 g7 a0 K( }+ w: B* QO_CREAT (创建)
* c; _' L* B8 O, y2 C% @
' h$ a6 c% c# H# J创建一个消息队列. 使用这个参数需要追加2个参数: ③mode(类型是mode_t), 和④attr(类型是mq_attr*).
2 N. `: ^9 p4 S5 e; j0 j如果name参数指定的消息队列已经存在, 那么这个参数将不起任何作用, 除非像下面 O_EXCL 中提到的情况;& d3 o: @" J4 Q' k2 V
否则, 会创建一个空的消息队列. 消息队列的用户ID会被设置成这个进程的实际的用户ID.
# N, d% x$ t9 r, M+ n( k 消息队列的组ID会被设置成这个进程的实际的组ID; 然而, 如果参数name 指向的消息队列在文件系统中可见, 那么组ID会被设置成包含消息队列的目录的组ID.
I+ j; J2 P3 T# k! m0 l如果参数mode中的位与文件权限中位不同,这种情况是未定义的.
: o& D7 `9 s! j4 E如果 attr 是 NULL, 创建的消息队列是系统实现的默认属性. 如果 attr 不是 NULL 并且调用进程对参数name指定的文件有特定的权限(什么权限),) t: O- I5 D/ Z J6 Z9 Y6 S
那么消息队列的属性 mq_maxmsg 和 mq_msgsize 会被设置成 attr 中的属性. 属性 mq_flags 和 mq_curmsgs 会被忽略.
" I5 `3 u$ l2 q! n! m# i O1 `如果 attr 不是 NULL , 并且调用进程对参数name指定的文件没有特定的权限,函数 mq_open() 会返回失败,不会创建消息队列.* a" M. T) R2 m1 @( u
" D' k4 ]* T& K$ }
' [2 i5 k+ D: f3 _+ w; bO_EXCL (既存检查)7 ~+ K% Z% ]4 X% z4 X) |
$ f: H* h1 ]: u$ q如果 O_EXCL 和O_CREAT同时被设置了, 如果消息队列应经存在,那么函数 mq_open() 会返回失败.9 O! [9 \4 p5 t; E4 G \7 t9 \; x, }
提供了检查消息队列是否存在的方法, 如果设置了 O_EXCL 必须同时设置 O_CREAT 否则结果未定义.3 `1 X/ J9 C$ m6 h' K
1 b* U7 Y/ I- A0 W6 C" c% PO_NONBLOCK (非阻塞)
0 u: q; {) X3 h6 x" R. n% d& y& y9 `6 O
决定函数 mq_send() 和 mq_receive() 在获取当前无法获得的资源或消息时,是一直等待(阻塞), 还是返回失败并将 errno 设置成 [EAGAIN]; $ |! t8 S( ^# e
) S! `/ Z+ u$ X. e( B0 O z- S0 e% \2 c$ F d* C4 R. h6 L0 E7 x
RETURN VALUE. r0 E# f5 w" f7 x( v
6 V& _$ _! w7 S7 v: ^如果函数执行成功, 函数返回一个描述符; @; [$ i; _1 H+ m1 f
8 t. D+ V" J5 W) f; K/ i* g如果函数执行失败,函数返回 (mqd_t)-1 并且设置errno,errno的种别详见下面的ERRORS一节.; U5 F* [+ j q0 i: f
. n: V2 R0 j& r2 N; a
: h% x' e( U- u0 m8 o3 E0 o# V
) m/ I' \! x5 ~' T, m- Y" mERRORS8 K) B( t. V2 ?8 a! a3 `7 `$ [
, d0 l, @# V. j5 i( F! W. ][EACCES]9 j: ~& \7 g1 a K
; Z F% r( R7 i; ?/ _7 K7 [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." g3 Z/ v+ @3 E4 E, k
- u% }/ X6 u2 P0 }4 i u[EEXIST]; V6 ^3 n' Q m7 K
( Y: B& |: h. T4 i
O_CREAT and O_EXCL are set and the named message queue already exists.
, I6 i/ }, J0 b; g6 v3 Y4 A7 o) N
[EINTR]
. X1 k6 p' G+ w6 [( E6 o+ e2 t. S) g; i" @7 I$ g7 o
函数 mq_open() 被信号中断.
5 q8 a' G8 {! G- P. L' e/ a3 b% R' d. i7 Z
[EINVAL]+ ]7 r0 d2 [7 Z' Z7 B1 a2 C
7 f+ x: ^" i- a# Z+ s" V函数 mq_open() 不支持参数name指定的路径.
4 ~' a. E/ E* J* S; y; K! t! M3 r! I
[EINVAL]6 t, ]0 x7 s" C g& I( w5 x
0 A* c3 p1 q, ^设置了O_CREAT标志, 参数3 attr 不是NULL;并且 mq_maxmsg 或 mq_msgsize 小于等于0.
" {" R N& V- |+ x- {/ P6 w l" f5 l) c- H+ \
[EMFILE]) m x+ d4 M8 z/ {- E
. ^2 i4 @$ d X6 }) d b
本进程中使用了过多的消息队列描述符 或 文件描述符.
6 `1 A4 [" h) e$ n7 i) B3 t1 Y, H* e8 i0 _
[ENFILE]
4 l' r) _3 a- [4 j x4 c6 r2 A$ c; r, S, p5 t! k7 k* Q
系统中打开的消息队列数目超过了系统支持的最大数.
# }1 @6 Z2 C3 f# q
4 H/ v7 x8 g6 Y[ENOENT]
6 b( a. E* ]9 j7 w7 Z/ D' {, ]. F" Q0 s; d6 f- w
没有设置O_CREAT标志,并且指定的消息队列不存在.
3 ^/ ]1 a! ?) q9 h4 _4 H& J! V: Z% S( B% J |3 ^! g& \
[ENOSPC]
) p2 G4 y% d/ G
6 [( n+ [2 l. p. W- K6 X空间不足,无法创建新的消息队列.
; s4 n7 g+ R% b) [. K: ?$ l. T
% N1 f+ _5 e* m( ~9 Z C[ENAMETOOLONG]
, }% U/ e9 c4 |+ v8 ?: E# n6 R" t* y0 o8 }
参数 name 的长度超过系统定义的最大长度.( t& |% I. z( H
) V4 Q- G# F1 Y3 C" a+ f
在不支持XSI系统中,name 的长度超过了 {_POSIX_PATH_MAX},在支持XSI系统中,name 的长度超过了 {_XOPEN_PATH_MAX};或者# t+ d9 ^2 g! s. U" h
/ o# b' J. x: G H g0 y在不支持XSI系统中,某一级路径的长度超过了 {_POSIX_NAME_MAX},在支持XSI系统中,某一级路径的长度超过了 {_XOPEN_NAME_MAX};5 ]3 `- t5 G5 k/ {3 V
% n5 b2 [# w+ H8 r& G& _
EXAMPLES
/ R2 q0 V( J* ^* ? |
|