EDA365电子论坛网

标题: 分享mq_open函数 [打印本页]

作者: uqHZau    时间: 2021-4-27 10:06
标题: 分享mq_open函数

$ _) p) G) K* QNAME
# }  v9 ?( |* n4 ~6 `mq_open - 打开一个消息队列 (REALTIME)
4 x" ^8 j% z5 ?. r! B/ K# B0 o$ Z) ?2 t5 k" k2 K: ~
7 r8 b8 }: q$ O7 H7 W/ q
SYNOPSIS) o) R6 D+ P6 i+ r0 _$ z+ M
5 S3 |7 a" Z3 I' ~, I" [* E2 [

) j- H' y! |: ]3 w* _# v. t% s" J" y8 X: B( y8 Y, H& Z: n
DESCRIPTION
! q: z3 B  I+ n$ p# z( Q5 J
' O9 c, ]* E/ ?% p2 A6 ?, mmq_open() 函数会通过一个消息队列描述符(类型是mqd_t)建立一个进程与一个消息队列的连接.' @. q, s4 m+ g/ S2 s4 |4 c9 w

1 n" W0 }5 N! u* c; R5 T3 Q该函数会创建一个打开的消息队列的描述符, 其他函数就可以通过这个描述符操作消息队列.
2 Y! z5 B9 D6 ]- ?* R% [) B" [; ?2 u  p0 v4 w- m
. j8 Z7 o+ Z5 o% p- z' K- G+ I
PARAMETERS
; m. j3 w+ W9 `8 Q; g
* N* F) ~5 ?) V! S' x* f) I①name
* [$ W) e- `/ P3 p参数 name 是一个指向消息队列名称的指针. 但是名字是否出现在文件系统中,是否对其他以路径名为参数的函数可见是未定义的.
7 k9 |: m3 G' ?! I& a5 `8 `6 ~4 K7 N, s! W
参数 name 的长度限制是由系统实现决定的(如何获取这个限制),不需要遵守路径名的限制 {PATH_MAX} 和 {NAME_MAX}.
; Z% [# s0 c' Y0 ]/ e/ G( |3 ]) l
( Y/ a0 ^9 y3 k" k) S如果 name 参数以"/"字符开头, 只有name没有被删除,所有使用相同name值调用mq_open函数的线程,访问的都是同一个消息队列,
0 |) ]- z" T. [8 d
- A% \1 ]$ b3 K" f6 j- e! L如果 name 参数不是以"/"字符开头,效果是由系统实现决定的.所以name参数一定要以"/"字符开头.. I- Q/ F1 `! j4 b1 N) g+ D7 F- Q
# k" V7 G1 x. Y
3 S0 _# X5 J/ f$ i
②oflag
: K7 [& {. |* n
  q, Y; I  L5 {+ O参数 oflag 表示想要访问(receive/send)消息队列的方式.# D" s% Y1 X' z, V2 r0 j( j6 ~3 ]
, d4 @6 `+ m+ ~7 D0 F2 L7 Q# D
参数 oflag 是由下列宏组合计算出来的, 注意必须包含前3个(访问模式) 中的一个:5 u: k' I* R; D* U  Z

8 u4 H/ H4 _# a* B$ rO_RDONLY (只读)
; K# b! B5 U# F' T# C0 D9 [
  `. ?6 q: D1 I' H6 U, s9 P  k打开一个消息队列用来接受消息.
! e- h" A5 k; u3 A; P* P
8 S4 b. N9 D: m5 w$ W调用进程可以使用mq_open返回的描述符用于函数 mq_receive(), 但是不能用于函数 mq_send().. _+ W9 t% z0 w0 V

8 S3 A, N& n8 q( u一个消息队列可以在相同或不同的进程中多次打开用来接收消息.
  Q" b  }, G" n3 [% I: B6 {. d8 O! ]' G: d- y% e
O_WRONLY (只写)- K8 a; U8 v/ e

, F% g- y0 c6 W/ g打开一个消息队列用来发送消息.+ Z4 \$ ]' @) T7 r% t- C0 ~0 {
) R0 Y! w1 |/ m
调用进程可以使用mq_open返回的描述符用于函数 mq_send(), 但是不能用于函数 mq_receive().
  o$ u  |* I9 `* g7 R$ `. h7 E: t1 `8 _. L# O$ \
一个消息队列可以在相同或不同的进程中多次打开用来发送消息.
& h- M# W+ \+ Y* ^/ x$ x; a) N0 C5 l
O_RDWR (读写)& Q7 G( j  v) N9 _) e, `
9 }5 @0 L1 B4 q6 Y2 V
打开一个消息队列用即可用来发送消息也可以用来接受消息.9 n) b- ]) J2 M3 j& o/ q

) `# e: C$ A& V调用进程可以使用任何支持O_RDONLY 和O_WRONLY 访问模式的函数.
1 W! V0 a# @. d0 |0 Z  M( M2 M1 @: T# a
一个消息队列可以在相同或不同的进程中多次打开用来发送消息.# W1 z9 H0 U& _, \7 b& T' I

+ c& z: x/ R) X2 J( S1 E! A
1 D! N, t( ]8 C3 U7 R: |3 f  H- N* @' x! O2 L! j( ?# \
Any combination of the remaining flags may be specified in the value of oflag:
& ]7 q5 P# x( ^8 K1 a) ]/ n
; h; Q) T0 Q4 k2 ^6 W7 u' v  d$ v4 S6 Q! V, M
O_CREAT (创建)- u; a& [; X3 m, h( `$ z

- d! l1 o5 I/ T: B  S& ]' e创建一个消息队列. 使用这个参数需要追加2个参数: ③mode(类型是mode_t), 和④attr(类型是mq_attr*).
( e1 E* U; R& d1 Q如果name参数指定的消息队列已经存在, 那么这个参数将不起任何作用, 除非像下面 O_EXCL 中提到的情况;
5 i, R: M, Z- e/ P# x) {; m否则, 会创建一个空的消息队列. 消息队列的用户ID会被设置成这个进程的实际的用户ID.- y5 o! J' I8 p, Y
消息队列的组ID会被设置成这个进程的实际的组ID; 然而, 如果参数name 指向的消息队列在文件系统中可见, 那么组ID会被设置成包含消息队列的目录的组ID.: q8 t: A$ x  \
如果参数mode中的位与文件权限中位不同,这种情况是未定义的.
  T' o: o8 D" W4 P如果 attr 是 NULL, 创建的消息队列是系统实现的默认属性. 如果 attr 不是 NULL 并且调用进程对参数name指定的文件有特定的权限(什么权限),( X6 f5 V" {. p4 `
那么消息队列的属性 mq_maxmsg 和 mq_msgsize 会被设置成 attr 中的属性. 属性 mq_flags 和 mq_curmsgs 会被忽略.$ Q1 P" |( ?% d! C* _3 ]0 \
如果 attr 不是 NULL , 并且调用进程对参数name指定的文件没有特定的权限,函数 mq_open() 会返回失败,不会创建消息队列.
  e+ N" R( g) S! k; l' {& `% G$ u3 d( y, Y: t8 z8 u

( C* r2 R; s: `# R+ P9 \, LO_EXCL (既存检查)% b& N, t' r( \* @& ?
' f* F& B$ T2 q: K
如果 O_EXCL 和O_CREAT同时被设置了, 如果消息队列应经存在,那么函数 mq_open() 会返回失败.3 O( E% t) F4 M! V' k8 }
提供了检查消息队列是否存在的方法, 如果设置了 O_EXCL 必须同时设置 O_CREAT 否则结果未定义.: G' B$ J: G; W/ n. R8 b/ ]* T  e, g

3 q/ f6 \& Z. t# C+ a" n0 X9 qO_NONBLOCK (非阻塞)
  B) B5 [' x# h% N9 H+ L9 O
; n$ {( D* q5 a5 m2 C% F- ?决定函数 mq_send() 和 mq_receive() 在获取当前无法获得的资源或消息时,是一直等待(阻塞), 还是返回失败并将 errno 设置成 [EAGAIN]; ; c( Q7 [1 Z1 @8 _( ?6 ]

* u' {5 r4 e9 n( K$ |% T
2 E5 {4 }& w- ^4 j1 v' }8 o. SRETURN VALUE
. b: \& A3 R" u; h% ?6 W6 K: D1 s
如果函数执行成功, 函数返回一个描述符
7 k& i) f5 Y; @1 n
  n$ u3 h5 v6 ]' i0 E如果函数执行失败,函数返回 (mqd_t)-1 并且设置errno,errno的种别详见下面的ERRORS一节.
, r% p* T* f7 l0 P% S  r) A8 I, _% [5 O$ ?! D
, l2 E3 N8 S( ]* W- y' j1 S

% ]0 ?& A. ?* sERRORS
: N- K/ B3 h( A( R& t5 u% M! {5 K, A* ~5 n$ p
[EACCES]
/ Q/ {8 G: S1 L; p+ j  j
1 _; o0 W$ `+ q/ V1 G* hThe 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.0 {. M0 a1 D$ o, O$ F/ d

5 w. R2 b- [; B, C[EEXIST]
$ K3 s& l. u3 P% l. l) b+ X- y# C0 c0 j' \/ {& E7 c* k8 i
O_CREAT and O_EXCL are set and the named message queue already exists.
, c6 j$ @! o) E1 n2 Y+ z- t: s3 \, h1 n4 B2 [3 \1 W0 z
[EINTR]" S+ V  U. D$ L) U, u4 j
4 f+ l0 t6 r- Q' a$ z
函数 mq_open() 被信号中断.8 R1 G6 m+ p9 E

2 h! Q  N: o  M  b6 S+ u/ \% a6 i' P1 b6 B[EINVAL]  p: ?( h/ \3 t8 z- i0 [

* [9 ^/ h  O9 H4 ]" R( e+ N函数 mq_open() 不支持参数name指定的路径.
4 N2 t( Q4 W% U+ w! E* a4 M. J
& n+ |, |* Z5 S( j) K[EINVAL]
2 x$ V; ?# p7 E0 e3 ?( Q* ?. ]% v9 ?: G% t" j0 c6 E& ^
设置了O_CREAT标志, 参数3 attr 不是NULL;并且 mq_maxmsg 或 mq_msgsize 小于等于0.4 F8 H: K# ~5 N9 _" g  B: K

4 @5 I" l% T: m: Q! g[EMFILE], [/ W% V" e* D6 t9 T: G# ]$ u

# c; ^7 G1 c. @本进程中使用了过多的消息队列描述符 或 文件描述符.
% \! s3 l; r' i8 i" I- _/ k( M5 N& F# I: L8 K
[ENFILE]
& K" Z' g  Q* K( S6 ^
5 j" y) }& ~2 ]% K8 D3 N系统中打开的消息队列数目超过了系统支持的最大数.
- m) B. g1 |- c# W/ [* Z0 a
. s! U0 ?* v1 P% U7 O[ENOENT]
5 V  N) _% d! q2 y7 J/ |* ^- {0 l1 B% E3 S; D/ u8 N' d9 G- p; T
没有设置O_CREAT标志,并且指定的消息队列不存在.4 f" d) O) i. Q7 z3 p; z) j( w

7 Q& B& x6 P3 H" `4 I2 q[ENOSPC]" C6 h% n: o4 m8 ?/ o  R  {1 W# |
. I* L  [) [" c, N, ?
空间不足,无法创建新的消息队列.
& \. X% {0 P3 f' _# A, U) q. t
1 Q. K, ?9 l8 d( N[ENAMETOOLONG]! x" U+ e+ W6 o0 [0 q
! j( {8 ^8 n1 @" |( X4 c+ f
参数 name 的长度超过系统定义的最大长度.& ~7 v6 k8 H; O* k" e( c2 v& |
/ n) D( J* j& T8 D7 \
在不支持XSI系统中,name 的长度超过了 {_POSIX_PATH_MAX},在支持XSI系统中,name 的长度超过了 {_XOPEN_PATH_MAX};或者
2 V4 Y; ]$ A! W% }: _0 l9 D% b) r7 v& o! }/ x# F* F0 p/ C
在不支持XSI系统中,某一级路径的长度超过了 {_POSIX_NAME_MAX},在支持XSI系统中,某一级路径的长度超过了 {_XOPEN_NAME_MAX};
+ v% T5 ?- p) T$ y$ }4 g" S5 _! m! Y$ }4 ]! @2 x: V
EXAMPLES7 \; o1 W. o! S

作者: SsaaM7    时间: 2021-4-27 10:56
分享mq_open函数




欢迎光临 EDA365电子论坛网 (https://bbs.eda365.com/) Powered by Discuz! X3.2