posix消息队列使用全面介绍
华为LiteOS开发介绍
struct LOS_DL_LIST list;
…… struct SensorOperation *sensorOp; // Init、Open、Close、IoCtl
…… UINT8
tag;
// 类别标签
UINT8
cmd;
UINT8
sensorStat;
} SensorType;
42
LiteOS开发
• POSIX NP:SMP • LIBC、LIBM: • C++:STL • CMSIS:暂不建议用。
46
华为LITEOS
• LiteOS介绍 • LiteOS内核 • LiteOS开发 • LiteOS移植
47
LITEOS移植
• 目标板目录文件 • 工具 • 生成裸机工程 • 文件准备 • 配置 • 接口封装 • 驱动框架
• 读写互斥:逻辑解决,避免用锁。 • 时间不敏感:互斥锁 • 时间敏感:自旋锁(尽量不用) • 队列:自定义循环队列。
36
华为LITEOS
• LiteOS介绍 • LiteOS内核 • LiteOS开发 • LiteOS移植
37
LITEOS开发
• 开发工具 • 功能组件 • 维测 • 标准库
38
43
LiteOS开发
功能组件
• GUI
44
LiteOS开发
维测
• CPU占用率 • Trace • LMS • Shell • 调度统计 • 内存调测 • 任务间通信调测:队列、锁 • 临终遗言 • 魔法键。
45
LiteOS开发
标准库
• POSIX: • 消息队列 • 线程(任务) • 信号量 • 时间、定时器
ldap posixgroup 用法
LDAP(Lightweight Directory Access Protocol)是一种用于访问和维护分布式目录服务的协议。
在LDAP中,posixGroup是一种对象类(object class),用于表示包含一组用户的群组。
posixGroup可以用于管理用户和组的身份和权限。
要使用posixGroup,首先需要在LDAP目录中定义一个posixGroup对象。
下面是一个典型的posixGroup对象的LDIF(LDAP Data Interchange Format)示例:```dn: cn=mygroup,ou=groups,dc=example,dc=comobjectClass: topobjectClass: posixGroupcn: mygroupgidNumber: 10000memberUid: user1memberUid: user2```在这个示例中,我们创建了一个名为mygroup的posixGroup对象。
它具有以下属性:- `cn`:群组的通用名称(Common Name)- `objectClass`:对象类,必须包含posixGroup- `gidNumber`:群组的GID(Group ID)- `memberUid`:属于该群组的用户的用户名要使用posixGroup对象,可以执行以下操作:1. 创建posixGroup对象:使用适当的LDAP客户端工具(如ldapadd)将上述示例LDIF导入到LDAP目录中,以创建posixGroup对象。
2. 添加用户到posixGroup:修改posixGroup对象的`memberUid`属性,将用户添加为群组成员。
3. 查询posixGroup对象:使用适当的LDAP查询工具(如ldapsearch),根据需要检索posixGroup对象的属性和成员信息。
4. 删除posixGroup对象:使用适当的LDAP客户端工具,删除posixGroup对象及其相关属性。
进程间通信 IPC interprocess communication
进程间通信 IPC interprocess communication1,管道,FIFO2, 信号3,消息队列4,共享类存5.文件映射6.socket(1)管道(Pipe):管道可用于具有亲缘关系进程间的通信,允许一个进程和另一个与它有共同祖先的进程之间进行通信。
(2)命名管道(named pipe):命名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信。
命名管道在文件系统中有对应的文件名。
命名管道通过命令mkfifo或系统调用mkfifo来创建。
(3)信号(Signal):信号是比较复杂的通信方式,用于通知接受进程有某种事件发生,除了用于进程间通信外,进程还可以发送信号给进程本身;linux除了支持Unix早期信号语义函数sigal外,还支持语义符合Posix.1标准的信号函数sigaction(实际上,该函数是基于BSD的,BSD为了实现可靠信号机制,又能够统一对外接口,用sigaction函数重新实现了signal函数)。
(4)消息(Message)队列:消息队列是消息的链接表,包括Posix消息队列system V 消息队列。
有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。
消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺(5)共享内存:使得多个进程可以访问同一块内存空间,是最快的可用IPC形式。
是针对其他通信机制运行效率较低而设计的。
往往与其它通信机制,如信号量结合使用,来达到进程间的同步及互斥。
(6)内存映射(mapped memory):内存映射允许任何多个进程间通信,每一个使用该机制的进程通过把一个共享的文件映射到自己的进程地址空间来实现它。
(7)信号量(semaphore):主要作为进程间以及同一进程不同线程之间的同步手段。
(8)套接口(Socket):更为一般的进程间通信机制,可用于不同机器之间的进程间通信。
posix消息队列使用全面介绍
POSIX消息队列是linux进程间通信的重要方式,下面按照创建,使用,关闭的顺序讲述了POSIX消息队列的使用方法:创建POSIX消息队列:mq_open#include<mqueue.h>mqd_t mq_open(const char *name,int oflag,int mode,mq_addr *attr);参数说明:Name:消息队列的名字字符串,必须以’/’开头,否则会出错。
Oflag: 表示打开的方式,1.首先必须说明读写方式,可以使以下的值之一:O_RDONLY:建立的队列是只读的O_WRONLY:建立的队列是只写的O_RDWR:建立的队列是可读可写2.必须有O_CREATE,说明是创建消息队列。
3.还有可选的选项:O_NONBLOCK:说明在创建的队列上发送和接收消息时,如果没有资源,不会等待,之间返回,如果不设置这个选项,缺省是会等待。
O_EXCL:在创建队列时,检测要创建的队列的名字是否已经存在了,如果已存在,函数会返回出错可以以或的方式形成Oflag,例如:O_RDWR|O_CREAT|O_EXCL Mode:是一个可选参数,在oflag中含有O_CREA T标志且消息队列不存在时,才需要提供该参数。
表示默认的访问权限,这个权限和文件访问的权限是相同的,取值也相同。
Mode可以由多个值组合而成,如:S_IRUSR|S_IWUSR,队列的所有者有读和写的权限。
Attr:指向结构struct mq_attr的指针。
我们可以在创建队列时通过这个结构设置队列的最大消息数和每个消息的最大长度。
struct mq_attr{long mq_flags; // 0或者O_NONBLOCK,说明是否等待long mq_maxmsg; //队列中包含的消息数的最大限制数long mq_msgsize; //每个消息大小的最大限制数long mq_curmsgs; //当前队列中的消息数}mq_maxmsg和mq_msgsize属性只能在创建消息队列时通过mq_open来设置。
消息队列的使用方法
消息队列的使用方法消息队列是一种用于在不同的系统和应用程序之间传递和传输数据的中间件。
它使用先入先出(FIFO)的方式存储和分发消息,可以提高系统的可靠性、扩展性和性能。
在实际应用中,消息队列有着广泛的使用场景,包括异步处理、解耦系统组件、削峰填谷、流量控制以及实现可靠的消息传递等。
下面将详细介绍消息队列的使用方法。
1.选择消息队列在开始使用消息队列之前,需要根据实际需求选择适合的消息队列。
常见的消息队列有Kafka、RabbitMQ和ActiveMQ等。
选择时,需要考虑消息的延迟要求、系统的可用性、消息吞吐量等因素。
2.定义消息格式在使用消息队列之前,需要定义消息的格式。
消息的格式应该简洁清晰,包含必要的信息,并考虑消息的扩展性和兼容性。
可以使用JSON、XML或者自定义的消息格式。
3.创建消息生产者消息生产者负责生成和发送消息到消息队列。
在创建消息生产者时,需要指定消息队列的地址和端口,并进行身份验证(如果需要)。
然后,通过消息队列提供的API,将消息发送到指定的队列中。
4.创建消息消费者消息消费者用于接收处理消息队列中的消息。
消费者需要连接到消息队列,并订阅一个或多个队列。
通过注册回调函数,消费者可以在消息到达时对消息进行处理。
5.异步处理消息一般情况下,消息队列的主要优势在于它可以实现异步处理。
消息生产者发送消息之后,可以立即返回,而不需要等待消息被消费者处理。
这种异步处理方式可以提高系统的性能和吞吐量。
6.解耦系统组件消息队列可以将系统中的各个组件解耦,使得它们可以独立运行和扩展。
消息生产者和消费者不需要直接知道对方的存在,它们只需要连接到消息队列即可。
7.削峰填谷消息队列可以用于平滑处理系统中的峰值流量。
当流量高峰到来时,消息队列可以暂时保存消息,等到系统负载下降时再进行消费。
这样可以避免系统因流量突增而崩溃。
8.流量控制通过设置合适的缓冲区大小和消费速率,消息队列可以实现流量控制。
L-IPC
25
有名管道的创建可以使用函数 mkfifo(),该函 数类似文件中的open()操作,可以指定管道的路 径和打开的模式。 在创建管道成功之后,就可以使用open、read、 write这些函数了。与普通文件的开发设置一样, 对于为读而打开的管道可在open中设置 O_RDONLY,对于为写而打开的管道可在open中设 置 O_WRONLY,在这里与普通文件不同的是阻塞 问题。由于普通文件的读写时不会出现阻塞问题, 而在管道的读写中却有阻塞的可能,这里的非阻 塞标志可以在open函数中设定为 O_NONBLOCK。
26
对于读进程 若该管道是阻塞打开,且当前 FIFO 内没有数 据,则对读进程而言将一直阻塞直到有数据写 入。 若该管道是非阻塞打开,则不论 FIFO 内是否 有数据,读进程都会立即执行读操作。 对于写进程 若该管道是阻塞打开,则写进程而言将一直阻 塞直到有读进程读出数据。 若该管道是非阻塞打开,则当前 FIFO 内没有 读操作,写进程都会立即执行读操作。
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGIOT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR 在Alpha AXP Linux系统上,信号的编号有些不同。
mq_notify用法
mq_notify 是POSIX 消息队列库中的一个函数,它用于实现异步事件通知。
这个函数告诉POSIX 消息队列系统在某个空队列中放置了一个消息时产生一个信号或者创建一个线程来执行特定程序。
以下是mq_notify 的基本用法:
```c
#include <mqueue.h>
int mq_notify(mqd_t mqdes, const struct sigevent *notification);
```
其中,mqdes 是消息队列的描述符,notification 是一个指向sigevent 结构的指针,用于指定当一个消息到达时需要执行的操作。
sigevent 结构至少包含以下字段:
* sigev_notify :指定通知类型,可以为SIGEV_NONE、SIGEV_SIGNAL 或SIGEV_THREAD。
* sigev_signo :当通知类型为SIGEV_SIGNAL 时,这个字段指定了发送的信号。
* sigev_value :当通知类型为SIGEV_SIGNAL 或SIGEV_THREAD 时,这个字段指定了传递给处理函数或线程的参数。
* sigev_notify_function :当通知类型为SIGEV_THREAD 时,这个字段指定了被调用的函数。
该函数应返回一个int 值。
* sigev_notify_attributes :当通知类型为SIGEV_THREAD 时,这个字段指定了被调用函数的线程属性。
以上信息仅供参考,建议阅读POSIX 消息队列官方文档以获取更全面和准确的信息。
QNX中的进程间通信
QNX中的进程间通信(IPC)在QNX Neutrino中消息传递(Message passing)是IPC的主要形式,其他形式也都是基于消息传递来实现的。
QNX中提供了如下一个形式的IPC:Serive: Implemented in:・Message-passing Kernel・Signals Kernel・POSIX message queues External process・Shared memory Process manager・Pipes External process・FIFOs External process一、Synchronous message passing[同步消息传递]如果一个线程执行了MsgSend()方法向另一个线程(可以属于不同进程)发送消息,它会就被阻塞,直到目标线程执行了MsgReceive(),并处理消息,然后执行了MsgReply()。
如果一个线程在其他线程执行MsgSend()之前执行了MsgReceive(),它会被阻塞直到另一个线程执行了MsgSend()。
消息传递是通过直接的内存copy来实现的。
需要巨大消息传递的时候建议通过Shared Message[共享内存]或其他方式来实现。
1、消息传递中的状态迁移客户程序的状态迁移・SEND blocked:调用MsgSend()后,服务程序没有调用MsgReceive()的状态。
・REPLY blocked:调用MsgSend()后,并且服务程序调用了MsgReceive(),但是没有调用MsgReply()/MsgError()的状态。
当服务程序已经调用了MsgReceive()方法是,客户程序一旦调用MsgSend()就直接迁移如REPLY blocked状态。
・READY:调用MsgSend()后,并且服务程序调用了MsgReceive()和MsgReply()的状态。
服务程序的状态迁移:・RECEIVE blocked;调用MsgReceive()后,客户程序没有调用MsgSend()时的状态。
Linux message
消息队列消息队列(也叫做报文队列)能够克服早期unix通信机制的一些缺点。
作为早期unix通信机制之一的信号能够传送的信息量有限,后来虽然POSIX 1003.1b在信号的实时性方面作了拓广,使得信号在传递信息量方面有了相当程度的改进,但是信号这种通信方式更像"即时"的通信方式,它要求接受信号的进程在某个时间范围内对信号做出反应,因此该信号最多在接受信号进程的生命周期内才有意义,信号所传递的信息是接近于随进程持续的概念(process-persistent),见附录1;管道及有名管道及有名管道则是典型的随进程持续IPC,并且,只能传送无格式的字节流无疑会给应用程序开发带来不便,另外,它的缓冲区大小也受到限制。
消息队列就是一个消息的链表。
可以把消息看作一个记录,具有特定的格式以及特定的优先级。
对消息队列有写权限的进程可以向中按照一定的规则添加新消息;对消息队列有读权限的进程则可以从消息队列中读走消息。
消息队列是随内核持续的(参见附录1)。
目前主要有两种类型的消息队列:POSIX消息队列以及系统V消息队列,系统V消息队列目前被大量使用。
考虑到程序的可移植性,新开发的应用程序应尽量使用POSIX消息队列。
在本系列专题的序(深刻理解Linux进程间通信(IPC))中,提到对于消息队列、信号灯、以及共享内存区来说,有两个实现版本:POSIX的以及系统V的。
Linux内核(内核2.4.18)支持POSIX信号灯、POSIX共享内存区以及POSIX消息队列,但对于主流Linux发行版本之一redhad8.0(内核2.4.18),还没有提供对POSIX进程间通信API的支持,不过应该只是时间上的事。
因此,本文将主要介绍系统V消息队列及其相应API。
在没有声明的情况下,以下讨论中指的都是系统V消息队列。
一、消息队列基本概念1.系统V消息队列是随内核持续的,只有在内核重起或者显示删除一个消息队列时,该消息队列才会真正被删除。
实时系统中的POSIX及Case Study(五)
测试三(优先级翻转)所有配置的优先级翻转测试结果在图九中显示。
除了Lynx(lsem)案例的所有案例中,低优先级和高优先级任务共享一个用于保护资源的pthread互斥量。
没有负载的情况下,第一个Lynx配置的延迟时间与中优先级任务的延迟时间10毫秒有对应关系。
这说明了一个事实,LynxOS 3.0.1中,没有为pthread互斥量实现优先级继承。
Lynx信号量没有这个问题。
Solaris中实现了优先级继承,没有负载情况下,所有Solaris配置的延迟时间都比较低。
高负载情况下,只有Lynx(lsem)和Solaris(1 rt)配置显示了可接收的延迟时间。
Solaris 1rt和2 proc配置都受到了高负载的影响;因为缺乏优先级继承协议,Lynx配置仍然具有高延迟时间。
上下文切换时间。
表九显示了所有平台的上下文切换时间,从头两个同步测试中的内存信号量结果计算而来。
Lynx上下文切换时间比最好的Solaris配置下的时间的一半还少。
同样,Lynx的进程到进程上下文切换时间只稍微比线程到线程切换时间长一点。
Solaris线程上下文切换时间比进程切换时间确定得多。
Solaris(1 rt)配置下,最大线程到线程切换时间接近平均值。
然而,同样配置下,进程到进程切换时间比平均值差了一个数量级。
另一个有趣的发现是,Solaris下进程间切换时间比线程间切换时间还稍微好一些。
两种情况下,都存在LWP间的上下文切换,似乎说明了系统开销的bulk 在调度器中。
通信实时信号图十显示了所有配置下的实时信号benchmark结果。
Lynx配置比任何Solaris配置的信号延迟时间都小。
并且,Solaris 1 proc和Solaris 2 proc配置都被增加的非实时负载严重影响。
消息队列所有配置的POSIX消息队列延迟时间和吞吐量在表十中显示。
Lynx平台的延迟时间比Solaris平台好,但是Solaris 平台的吞吐量更好。
php-amqplib 用法
php-amqplib 是一个基于 PHP 的 AMQP 库,用于与 RabbitMQ 通信。
它提供了简单而强大的 API,使得在 PHP 应用中使用消息队列变得更加轻松和可靠。
在本文中,我们将介绍 php-amqplib 的基本用法,包括安装、连接、发送和接收消息等操作。
一、安装 php-amqplib1. 使用 Composer 进行安装要使用php-amqplib,首先需要在项目中使用Composer 进行安装。
在项目根目录下创建一个poser.json 文件,并添加以下内容:```json{"require": {"php-amqplib/php-amqplib": "^2.9"}}```然后在命令行中执行以下命令安装 php-amqplib:```bashcomposer install```2. 手动安装如果不使用 Composer,也可以手动安装 php-amqplib。
首先从GitHub 上下载最新的代码包,并解压到项目中。
然后在代码中使用require_once 导入 php-amqplib 的 autoloader:```phprequire_once 'path/to/php-amqplib/autoload.php';```二、连接到 RabbitMQ1. 创建连接使用 php-amqplib 连接到 RabbitMQ 非常简单。
首先创建一个连接对象,并指定 RabbitMQ 的主机名、端口号、用户名和密码:```php$connection = new\PhpAmqpLib\Connection\AMQPStreamConnection('localhost', 5672, 'guest', 'guest');```2. 创建通道连接成功后,需要创建一个通道对象,用于在 RabbitMQ 中进行消息的发布和接收操作:```php$channel = $connection->channel();```三、发送消息1. 定义交换机和队列在发送消息之前,需要先定义交换机和队列。
msgsnd的语法及用法
`msgsnd` 是POSIX 消息队列中的一个函数,用于将消息发送到消息队列中。
下面是`msgsnd`的语法及用法:```c#include <mqueue.h>int msgsnd(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned int msg_prio);```参数说明:* `mqdes`:消息队列描述符,通过`mqueue_open` 函数获得。
* `msg_ptr`:指向要发送的消息的指针。
* `msg_len`:消息的长度。
* `msg_prio`:消息的优先级。
`msgsnd`函数用于将一个消息发送到指定的消息队列中。
如果消息队列已满,则根据系统的配置,可能会阻塞或返回错误。
以下是一个使用`msgsnd` 的简单示例:```c#include <stdio.h>#include <stdlib.h>#include <mqueue.h>#define QUEUE_NAME "/test_queue"#define MAX_MSG_SIZE 1024#define MAX_MSGS 10int main() {mqd_t mq;char buffer[MAX_MSG_SIZE];unsigned int prio = 1;size_t msg_len;// 打开或创建消息队列mq = mqueue_open(QUEUE_NAME, O_CREAT | O_WRONLY, 0666, NULL);if (mq == (mqd_t)-1) {perror("mqueue_open");exit(EXIT_FAILURE);}// 发送消息for (msg_len = 0; msg_len < MAX_MSG_SIZE; msg_len++) { sprintf(buffer + msg_len, "Message length: %zu", msg_len);}if (msgsnd(mq, buffer, msg_len, prio) == -1) {perror("msgsnd");exit(EXIT_FAILURE);}printf("Message sent successfully\n");// 关闭消息队列if (mqueue_close(mq) == -1) {perror("mqueue_close");exit(EXIT_FAILURE);}return 0;}```在此示例中,我们使用`mqueue_open` 打开或创建名为`/test_queue` 的消息队列,并获得其描述符。
linux postthreadmessage 参数
linux postthreadmessage 参数Linux中的post_thread_message函数是一种线程间通信的方法,可以用来发送消息到目标线程的消息队列中。
本文将详细介绍post_thread_message函数的参数和使用方法。
post_thread_message函数是Linux下POSIX线程库提供的一个函数,它的原型如下:```cint post_thread_message(pthread_t thread, int msg_type, void *msg);```其中,参数解释如下:- `thread`:目标线程的线程ID,可以使用pthread_create函数创建线程时获取。
- `msg_type`:消息类型,可以是一个整数,用来区分不同的消息。
- `msg`:要发送的消息的内容,可以是任意类型的指针。
函数的返回值为0表示成功发送消息,否则返回一个错误码。
使用post_thread_message函数时,我们需要先创建目标线程并获得其线程ID。
下面是一个使用post_thread_message函数实现线程间通信的示例。
首先,我们需要在程序中定义一个全局变量来存储接收到的消息:```cvoid *received_msg;```然后,在目标线程的入口函数中,使用一个无限循环来接收消息,并根据消息类型进行相应的处理:```cvoid *thread_func(void *arg) {while(1) {int msg_type;void *msg;if(post_thread_message(pthread_self(), &msg_type, &msg) == 0) {switch(msg_type) {case MSG_TYPE_1:// 处理消息类型1break;case MSG_TYPE_2:// 处理消息类型2break;// 其他消息类型的处理}}}return NULL;}```在其他线程中,我们可以使用post_thread_message函数来向目标线程发送消息:```cint main() {// 创建目标线程,并获取线程ID保存在变量thread中pthread_t thread;pthread_create(&thread, NULL, thread_func, NULL);// 发送消息到目标线程int msg_type = MSG_TYPE_1;void *msg = "Hello, world!";post_thread_message(thread, msg_type, &msg);// 其他操作pthread_join(thread, NULL);return 0;}```在上面的示例中,我们首先创建了一个目标线程,并获取其线程ID保存在变量thread中。
POSIX标准理解
POSIX标准理解POSIX标准总体分析? POSIX,全称为可移植性操作系统接口,是一种关于信息技术的IEEE标准。
它包括了系统应用程序接口(简称API),以及实时扩展[C语言]。
该标准的目的是定义了标准的基于UNIX操作系统的系统接口和环境来支持源代码级的可移植性。
现在,标准主要提供了依赖C语言的一系列标准服务,再将来的版本中,标准将致力于提供基于不同语言的规范。
该标准对核心需求部分定义了一系列任何编程语言都通用的服务,这一部分服务主要从其功能需求方面阐述,而非定义依赖于编程语言的接口。
语言规范主要有两部分组成。
一部分包括了访问核心服务的编程语言的标准接口,这些核心服务为标准中基于编程语言的核心需求部分所定义;另一部分包含了一个特殊语言服务的标准接口。
基于任何语言,与该标准一致的执行都必须遵循语言规范的任何章节。
该标准一共被分为四个部分:(1)陈述的范围和一系列标准参考(第一章);(2)定义和总概念;(第二章)(3)各种接口设备;(第三章到第九章,第十一章到第十五章)(4)数据交换格式;(第十章)该标准的主要目的有:(1)面向应用(2)定义接口,而不是它的具体实现;(3)涉及资源和可移植性,而非对象;(4)基于c语言;(5)无超级用户,无系统管理;(6)最小限度的接口,最小限度的定义;(7)应用领域广泛;(8)对以前的实现进行最小限度改变;(9)对原有程序代码做最小的修改;(10)实时扩展;以下就对各个章节做简要分析。
第一章概述1.1范围定义范围的关键要素有:(1)定义足够的一套功能适用于实时应用程序领域的重要部分;(2)定义足够的实现规范和性能相关的函数,以便允许实时应用程序完成系统的确定性的响应;1.2?一致性系统须支持标准中定义的接口,系统能够提供标准中没有要求到的函数和工具。
在遵循于该标准的实现中,一种一致性文档是需要用到的,它必须具有与该标准相同的结构,包含有全名,数字,和标准所指示的日期,以及头文件<limits.h>和<unistd.h>中的界限值等等。
posix 消息队列原理
posix 消息队列原理POSIX消息队列是一种进程间通信的机制,它允许不同的进程通过消息进行数据交换。
在本文中,我们将探讨POSIX消息队列的原理,包括它的工作原理、特点和使用方法。
POSIX消息队列是一种可靠的、异步的通信机制,它允许进程通过发送和接收消息来进行通信。
与其他进程间通信机制相比,如管道或共享内存,POSIX消息队列具有以下优势:1. 高效性:POSIX消息队列使用内核缓冲区来存储消息,因此在发送和接收消息时不需要数据复制。
这使得消息队列在处理大量数据或频繁通信时更加高效。
2. 可靠性:消息队列提供了可靠的消息传递机制。
发送方可以确认消息是否已成功发送,接收方可以确认消息的发送者和消息的优先级。
3. 异步性:发送方和接收方可以独立地进行操作,不需要彼此等待。
这使得进程可以以自己的速度进行工作,而不受其他进程的影响。
4. 有序性:消息队列可以按照发送的顺序进行消息传递,保证了消息的有序性。
POSIX消息队列的工作原理如下:1. 创建消息队列:进程通过调用`mq_open`函数来创建一个消息队列。
在创建消息队列时,需要指定一个唯一的名称和一些属性,如消息的最大长度和最大数量。
2. 发送消息:发送方通过调用`mq_send`函数来向消息队列发送消息。
发送方需要指定消息队列的名称、消息的内容和消息的长度。
如果消息队列已满,发送方可以选择等待或立即返回。
3. 接收消息:接收方通过调用`mq_receive`函数来从消息队列接收消息。
接收方需要指定消息队列的名称、缓冲区的地址和缓冲区的大小。
如果消息队列为空,接收方可以选择等待或立即返回。
4. 关闭消息队列:进程通过调用`mq_close`函数来关闭消息队列。
关闭消息队列会释放相关的资源。
使用POSIX消息队列的步骤如下:1. 创建消息队列:调用`mq_open`函数来创建一个消息队列,指定消息队列的名称和属性。
2. 发送消息:调用`mq_send`函数来向消息队列发送消息,指定消息队列的名称、消息的内容和长度。
linuxposixmqueue
5)当该通知给发送给它的注册进程时,其注册即被撤销,该进程必须再次调用mq_notify以重新注册(如果想要的话)。
还有很多内容,请参看《unix网络编程2-进程间通信》
}
1)如果notification参数非空,那么当前进程希望在有一个消息到达所指定的先前为空的队列是得到通知,我们说“该进程被注册为接收该队列的通知”。
2)如果notification参数为空指针,而且当前进程目前被注册为接收所指定队列的通知,那么已存在的注册将被撤销。
3)任意时刻只有一个进程可以被注册为接收某个给定队列的通知。
#define QUEUE_MODE 0666
mqd_t OpenQueue(const char* QueueName);
mqd_t WriteToQueue(mqd_t QueueFd,char* Buf,size_t Len);
mqd_t CloseQueue(mqd_t QueueFd);
mqd_t RemoveQueue(const char* QueueName);
size_t ReadFromQueue(mqd_t QueueFd,char* buf,size_t Len);
size_t GetQueueMsgSize(mqd_t queueFd);
long GetCurMsgCount(mqd_t QueueFd);
该函数为只读队列建立或删除异步事件通知。sigevent结构是随Posix.1实时信号新加的,该结构以及本章中引入的所有新的信号相关常值都定义在<signal.h>头文件中
posix消息队列1
请教关于posix消息队列无法设置阻塞超时的问题请教老鸟:小菜在一个线程中创建一个posix消息队列,用mq_timedreceive来阻塞接收,发现在消息队列空的时候,并没有等待超时时间到达,而是立即返回。
不知道小菜在哪里出了问题,还望老鸟给于指教。
RHEL AS5.1内核版本2.6.18代码如下:消息队列创建:struct mq_attr newattr;mq_unlink("/m请问这个用到了什么知识qLcd");newattr.mq_maxmsg = 10;newattr.mq_curmsgs =0;newattr.mq_msgsize = sizeof(STRU_LCDMSG);if(ERROR == (msgQIdLcd = mq_open("/mqLcd", O_RDWR|O_CREAT, 0x777, &newattr))){PDBG_L0("LCD消息队列创建错误!\n");perror("<errno>");return;}接收消息队列如下:struct timespec tmout;_sec = 6;if(ERROR != (rcvlen = mq_timedreceive(msgQIdLcd, (char*)&struLcdMsgTmp, sizeof(STRU_LCDMSG), (unsigned *)NULL, (const struct timespec *)&tmout))) //if(ERROR != (rcvlen = mq_receive(msgQIdLcd, (char*)&struLcdMsgTmp, sizeof(STRU_LCDMSG), (unsigned *)NULL))){printf("receive a data, len = %d\n", rcvlen);}else{printf("rcv timeout\n");perror("<error>");printf("errno = %d\n", errno);}小菜偶发现用mq_receive可以正常阻塞,但用mq_timedreceive或mq_timedsend 就会立即返回,用gcc或arm-linux-gcc编译后都如此,请问我的问题可能出在哪里?希望大大们能够不吝指教,这个问题困惑小弟有段时间了,多谢了没有人用过么:em16:快两年了,也没有人回复,还是自己回复吧,以防有跟偶一样遇到这个问题的小菜搜到这篇帖子。
Posix消息队列接口说明(英文版)
最近看到的一些关于POSIX消息队列接口中文说明很粗略,现在提供其英文版详细说明NAMEmq_receive - receive a message from a message queue (REALTIME)SYNOPSIS#include <mqueue.h>ssize_t mq_receive(mqd_t mqdes, char *msg_ptr, size_t msg_len,unsigned int *msg_prio);DESCRIPTIONThe mq_receive()function is used to receive the oldest of the highest priority message(s) from the message queue specified by mqdes. If the size of the buffer in bytes, specified by the msg_len argument, is less than the mq_msgsize attribute of the message queue, the function fails and returns an error. Otherwise, the selected message is removed from the queue and copied to the buffer pointed to by the msg_ptr argument.If the value of msg_len is greater than {SSIZE_MAX}, the result is implementation-dependent.If the argument msg_prio is not NULL, the priority of the selected message is stored in the location referenced by msg_prio.If the specified message queue is empty and O_NONBLOCK is not set in the message queue description associated with mqdes, mq_receive() blocks until a message is enqueued on the message queue or untilmq_receive() is interrupted by a signal. If more than one thread is waiting to receive a message when a message arrives at an empty queue and the Priority Scheduling option is supported, then the thread of highest priority that has been waiting the longest will be selected to receive the message. Otherwise, it is unspecified which waiting thread receives the message. If the specified message queue is empty and O_NONBLOCK is set in the message queue description associatedwith mqdes, no message is removed from the queue, and mq_receive() returns an error.RETURN VALUEUpon successful completion, mq_receive()returns the length of the selected message in bytes and the message is removed from the queue. Otherwise, no message is removed from the queue, the function returns a value of -1, and sets errno to indicate the error.ERRORSThe mq_receive() function will fail if:[EAGAIN]O_NONBLOCK was set in the message description associated with mqdes, and the specified message queue is empty.[EBADF]The mqdes argument is not a valid message queue descriptor open for reading.[EMSGSIZE]The specified message buffer size, msg_len, is less than the message size attribute of the message queue.[EINTR]The mq_receive() operation was interrupted by a signal.[ENOSYS]The mq_receive() function is not supported by this implementation.The mq_receive() function may fail if:[EBADMSG]The implementation has detected a data corruption problem with the message.EXAMPLESNone.APPLICATION USAGENone.NAMEmq_send - send a message to a message queue (REALTIME)SYNOPSIS#include <mqueue.h>int mq_send(mqd_t mqdes, const char *msg_ptr, size_t msg_len,unsigned int msg_prio);DESCRIPTIONThe mq_send() function adds the message pointed to by the argument msg_ptr to the message queue specified by mqdes. The msg_len argument specifies the length of the message in bytes pointed to by msg_ptr. The value of msg_len is less than or equal to the mq_msgsize attribute of the message queue, or mq_send() fails.If the specified message queue is not full, mq_send() behaves as if the message is inserted into the message queue at the position indicated by the msg_prio argument. A message with a larger numeric value of msg_prio is inserted before messages with lower values of msg_prio. A message will be inserted after other messages in the queue, if any, with equal msg_prio. The value of msg_prio will be less than MQ_PRIO_MAX.If the specified message queue is full and O_NONBLOCK is not set in the message queue description associated with mqdes, mq_send() blocks until space becomes available to enqueue the message, or untilmq_send() is interrupted by a signal. If more than one thread is waiting to send when space becomes available in the message queue and the Priority Scheduling option is supported, then the thread of the highest priority that has been waiting the longest will be unblocked to send its message. Otherwise, it is unspecified which waiting thread is unblocked. If the specified message queue is full andO_NONBLOCK is set in the message queue description associated with mqdes, the message is not queued and mq_send() returns an error.RETURN VALUEUpon successful completion, the mq_send()function returns a value of zero. Otherwise, no message is enqueued, the function returns -1, and is set to indicate the error.ERRORSThe mq_send() function will fail if:[EAGAIN]The O_NONBLOCK flag is set in the message queue description associated with mqdes, and the specified message queue is full.[EBADF]The mqdes argument is not a valid message queue descriptor open for writing.[EINTR]A signal interrupted the call to mq_send().[EINVAL]The value of msg_prio was outside the valid range.[EMSGSIZE]The specified message length, msg_len, exceeds the message size attribute of the message queue.[ENOSYS]The function mq_send() is not supported by this implementation.EXAMPLESNone.APPLICATION USAGENone.NAMEmq_setattr - set message queue attributes (REALTIME)SYNOPSIS#include <mqueue.h>int mq_setattr(mqd_t mqdes, const struct mq_attr *mqstat,struct mq_attr *omqstat);DESCRIPTIONThe mq_setattr()function is used to set attributes associated with the open message queue description referenced by the message queue descriptor specified by mqdes.The message queue attributes corresponding to the following members defined in the mq_attr structure are set to the specified values upon successful completion of mq_setattr():mq_flagsThe value of this member is the bitwise logical OR of zero or more of O_NONBLOCK and any implementation-dependent flags.The values of the mq_maxmsg, mq_msgsize and mq_curmsgs members of the mq_attr structure are ignored by mq_setattr().If omqstat is non-NULL, the function mq_setattr() stores, in the location referenced by omqstat, the previous message queue attributes and the current queue status. These values are the same as would be returned by a call to mq_getattr() at that point.RETURN VALUEUpon successful completion, the function returns a value of zero and the attributes of the message queue will have been changed as specified. Otherwise, the message queue attributes are unchanged, and the function returns a value of -1 and sets errno to indicate the error.ERRORSThe mq_setattr() function will fail if:[EBADF]The mqdes argument is not a valid message queue descriptor. [ENOSYS]The function mq_setattr() is not supported by this implementation.EXAMPLESNone.APPLICATION USAGENone.NAMEmq_open - open a message queue (REALTIME)SYNOPSIS#include <mqueue.h>mqd_t mq_open(const char *name, int oflag, ...);DESCRIPTIONThe mq_open()function establishes the connection between a process and a message queue with a message queue descriptor. It creates a open message queue description that refers to the message queue, and a message queue descriptor that refers to that open message queue description. The message queue descriptor is used by other functions to refer to that message queue. The name argument points to a string naming a message queue. It is unspecified whether the name appears in the file system and is visible to other functions thattake pathnames as arguments. The name argument conforms to the construction rules for a pathname. If name begins with the slash character, then processes calling mq_open() with the same value of name refer to the same message queue object, as long as that name has not been removed. If name does not begin with the slash character, the effect is implementation-dependent. The interpretation of slash characters other than the leading slash character in name is implementation-dependent. If the name argument is not the name of an existing message queue and creation is not requested, mq_open()fails and returns an error.The oflag argument requests the desired receive and/or send access to the message queue. The requested access permission to receive messages or send messages is granted if the calling process would be granted read or write access, respectively, to an equivalently protected file.The value of oflag is the bitwise inclusive OR of values from the following list. Applications specify exactly one of the first three values (access modes) below in the value of oflag:O_RDONLYOpen the message queue for receiving messages. The process can use the returned message queue descriptor with mq_receive(), but not mq_send(). A message queue may be open multiple times in the same or different processes for receiving messages.O_WRONLYOpen the queue for sending messages. The process can use the returned message queue descriptor with mq_send()but not mq_receive(). A message queue may be open multiple times in the same or different processes for sending messages.O_RDWROpen the queue for both receiving and sending messages. The process can use any of the functions allowed for O_RDONLY and O_WRONLY. A message queue may be open multiple times in the same or different processes for sending messages.Any combination of the remaining flags may be specified in the value of oflag:O_CREATThis option is used to create a message queue, and it requires two additional arguments: mode, which is of type mode_t, and attr, which is a pointer to a mq_attr structure. If the pathname, name, has already been used to create a message queue that still exists, then this flag has no effect, except as noted under O_EXCL. Otherwise, a message queue iscreated without any messages in it. The user ID of the message queue is set to the effective user ID of the process, and the group ID of the message queue is set to the effective group ID of the process. The file permission bits are set to the value of mode. When bits in mode other than file permission bits are set, the effect is implementation-dependent.If attr is NULL, the message queue is created with implementation-dependent default message queue attributes. If attr is non-NULL and the calling process has the appropriate privilege on name, the message queue mq_maxmsg and mq_msgsize attributes are set to the values of the corresponding members in the mq_attr structure referred to by attr. If attr is non-NULL, but the calling process does not have the appropriate privilege on name, the mq_open()function fails and returns an error without creating the message queue.O_EXCLIf O_EXCL and O_CREAT are set, mq_open()fails if the message queue name exists. The check for the existence of the message queue and the creation of the message queue if it does not exist are atomic with respect to other processes executing mq_open()naming the same name with O_EXCL and O_CREAT set. If O_EXCL is set and O_CREAT is not set, the result is undefined.O_NONBLOCKThe setting of this flag is associated with the open message queue description and determines whether a mq_send() or mq_receive() waits for resources or messages that are not currently available, or fails with errno set to [EAGAIN]. See mq_send() and mq_receive() for details.The mq_open() function does not add or remove messages from the queue.RETURN VALUEUpon successful completion, the function returns a message queue descriptor. Otherwise, the function returns ( mqd_t )-1 and sets errno to indicate the error.ERRORSThe mq_open() function will fail if:[EACCES]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.[EEXIST]O_CREAT and O_EXCL are set and the named message queue alreadyexists.[EINTR]The mq_open() operation was interrupted by a signal.[EINVAL]The mq_open() operation is not supported for the given name. [EINVAL]O_CREAT was specified in oflag, the value of attr is not NULL, and either mq_maxmsg or mq_msgsize was less than or equal to zero.[EMFILE]Too many message queue descriptors or file descriptors are currently in use by this process.[ENAMETOOLONG]The length of the name string exceeds {PATH_MAX}, or a pathname component is longer than {NAME_MAX} while _POSIX_NO_TRUNC is in effect.[ENFILE]Too many message queues are currently open in the system. [ENOENT]O_CREAT is not set and the named message queue does not exist. [ENOSPC]There is insufficient space for the creation of the new message queue. [ENOSYS]The function mq_open() is not supported by this implementation.EXAMPLESNone.APPLICATION USAGENone.SEE ALSONAMEmq_close - close a message queue (REALTIME)SYNOPSIS#include <mqueue.h>int mq_close(mqd_t mqdes);DESCRIPTIONThe mq_close()function removes the association between the message queue descriptor, mqdes, and its message queue. The results of using this message queue descriptor after successful return from this mq_close(), and until the return of this message queue descriptor from a subsequent mq_open(), are undefined.If the process has successfully attached a notification request to the message queue via this mqdes, this attachment will be removed, and the message queue is available for another process to attach for notification.RETURN VALUEUpon successful completion, the mq_close()function returns a value of zero; otherwise, the function returns a value of -1 and sets errno to indicate the error.ERRORSThe mq_close() function will fail if:[EBADF]The mqdes argument is not a valid message queue descriptor. [ENOSYS]The function mq_close() is not supported by this implementation.EXAMPLESNone.APPLICATION USAGENone.SEE ALSONAMEmq_unlink - remove a message queue (REALTIME)SYNOPSIS#include <mqueue.h>int mq_unlink(const char *name);DESCRIPTIONThe mq_unlink() function removes the message queue named by the pathname name. After a successful call to mq_unlink() with name, a call to mq_open() with name fails if the flag O_CREAT is not set in flags. If one or more processes have the message queue open when mq_unlink() is called, destruction of the message queue is postponed until all references to the message queue have been closed. Calls to mq_open()to re-create the message queue may fail until the message queue is actually removed. However, the mq_unlink() call need not block until all references have been closed; it may return immediately.RETURN VALUEUpon successful completion, the function returns a value of zero. Otherwise, the named message queue is unchanged by this function call, and the function returns a value of -1 and sets errno to indicate the error.ERRORSThe mq_unlink() function will fail if:[EACCES]Permission is denied to unlink the named message queue. [ENAMETOOLONG]The length of the name string exceeds {NAME_MAX} while _POSIX_NO_TRUNC is in effect.[ENOENT]The named message queue does not exist.[ENOSYS]The function mq_unlink() is not supported by this implementation.EXAMPLESNone.APPLICATION USAGENAMEmq_getattr - get message queue attributes (REALTIME)SYNOPSIS#include <mqueue.h>int mq_getattr(mqd_t mqdes, struct mq_attr *mqstat);DESCRIPTIONThe mqdes argument specifies a message queue descriptor. The mq_getattr() function is used to get status information and attributes of the message queue and the open message queue description associated with the message queue descriptor. The results are returned in the mq_attr structure referenced by the mqstat argument.Upon return, the following members will have the values associated with the open message queue description as set when the message queue was opened and as modified by subsequent mq_setattr() calls:mq_flagsThe following attributes of the message queue are returned as set at message queue creation.mq_maxmsgmq_msgsizemq_curmsgsThe number of messages currently on the queue.RETURN VALUEUpon successful completion, the mq_getattr()function returns zero. Otherwise, the function returns -1 and sets errno to indicate the error.ERRORSThe mq_getattr() function will fail if:[EBADF]The mqdes argument is not a valid message queue descriptor. [ENOSYS]The function mq_getattr() is not supported by this implementation.EXAMPLESNone.APPLICATION USAGENone.。
posix标准简介
posix标准简介
POSIX具有多重含义,通常指POSIX标准,该标准是一个可移植操作系统接口(Portable Operating System Interface),由IEEE提出,ANSI和ISO将其标准化。
POSIX的目的是使应用程序源代码可以在兼容POSIX的操作系统上移植。
理想的目标是应用程序移植到另一个操作系统只需要重新编译就可以运行。
POSIX最后一个字母“X”表达了这种超乎操作系统差异的理想。
目前并没有实现这种理想:从操作系统看,由于目标、要求、理念、条件的差异,并不是所有的操作系统都实现100%POSIX兼容;从应用程序看,很多代码编写使用了特定操作系统支持的调用,并没有很好地使用POSIX接口。
但是,很显然,使用POSIX接口的应用程序在兼容POSIX的操作系统间移植将是很轻松的事情。
POSIX标准是一个处于不断发展之中的庞大体系,包括:
1003.1 系统API
1003.2 SHELL及工具
1003.3 POSIX符合性测试方法
1003.5 ADA语言接口
1003.13 标准化可移植实时应用环境AEP
其中,POSIX 1003.1系列标准是POSIX最主体内容,也是我们最关心的部分。
该系列内容由如下主体定义以及一些扩展和增补组成:1003.1 1988年通过,基本OS接口
1003.1b 1993年通过,实时扩展
1003.1c 1995年通过,线程扩展
1003.1d 1999年通过,实时扩展
1003.1j 2000年通过,高级实时扩展
1003.1q 2000年通过,时间数据流跟踪。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
POSIX消息队列是linux进程间通信的重要方式,下面按照创建,使用,关闭的顺序讲述了POSIX消息队列的使用方法:创建POSIX消息队列:mq_open#include<mqueue.h>mqd_t mq_open(const char *name,int oflag,int mode,mq_addr *attr);参数说明:Name:消息队列的名字字符串,必须以’/’开头,否则会出错。
Oflag: 表示打开的方式,1.首先必须说明读写方式,可以使以下的值之一:O_RDONLY:建立的队列是只读的O_WRONLY:建立的队列是只写的O_RDWR:建立的队列是可读可写2.必须有O_CREATE,说明是创建消息队列。
3.还有可选的选项:O_NONBLOCK:说明在创建的队列上发送和接收消息时,如果没有资源,不会等待,之间返回,如果不设置这个选项,缺省是会等待。
O_EXCL:在创建队列时,检测要创建的队列的名字是否已经存在了,如果已存在,函数会返回出错可以以或的方式形成Oflag,例如:O_RDWR|O_CREAT|O_EXCL Mode:是一个可选参数,在oflag中含有O_CREA T标志且消息队列不存在时,才需要提供该参数。
表示默认的访问权限,这个权限和文件访问的权限是相同的,取值也相同。
Mode可以由多个值组合而成,如:S_IRUSR|S_IWUSR,队列的所有者有读和写的权限。
Attr:指向结构struct mq_attr的指针。
我们可以在创建队列时通过这个结构设置队列的最大消息数和每个消息的最大长度。
struct mq_attr{long mq_flags; // 0或者O_NONBLOCK,说明是否等待long mq_maxmsg; //队列中包含的消息数的最大限制数long mq_msgsize; //每个消息大小的最大限制数long mq_curmsgs; //当前队列中的消息数}mq_maxmsg和mq_msgsize属性只能在创建消息队列时通过mq_open来设置。
mq_open 只会设置该两个属性,忽略另外两个属性。
mq_curmsgs属性只能被获取而不能被设置。
当attr参数为NULL时则使用linux的默认值msg_max ,msgsize_max 。
而使用mq_open创建一个新的队列时,attr只能给它指定mq_maxmsg,mq_msgsize这两个属性。
mq_open忽略attr结构中的另外两个成员。
在创建过程中需要注意的是,指定的这两个属性都必须小于等于msg_max或者msgsize_max的。
查看系统中消息队列的这两个限制值的方法是:cat /proc/sys/fs/mqueue/msg_maxcat /proc/sys/fs/mqueue/msgsize_max系统默认值有些时候不够大,需要我们对这个限制数进行修改,方法如下:修改/etc/sysctl.conf 在这个文件中添加#mqueue max fs.mqueue.msg_max=100 fs.mqueue.msgsize_max=9000 fs.mqueue.queues_max=520 保存好后重启系统就好了。
返回值:函数的返回值是mqd_t类型,是消息队列的描述符。
这实际是一个整数。
当函数执行出错时,会返回-1.要注意的是,描述符对于不同的进程/线程是不一样的,因此不同的进程/线程不能使用其他进程/线程的描述符。
打开消息队列:当一个进程在使用消息队列发送和接收消息之前,必须先打开消息队列。
以获得专属于本进程的对于这个消息队列的描述符。
打开消息队列的函数和创建消息队列的函数是一样的,区别在于参数要少2个。
mqd_t mq_open(const char *name,int oflag,);参数:Name:消息队列的名字字符串,必须以’/’开头,否则会出错。
Oflag: 表示打开的方式,说明读写方式,可以使以下的值之一:O_RDONLY:建立的队列是只读的O_WRONLY:建立的队列是只写的O_RDWR:建立的队列是可读可写返回值:函数的返回值是mqd_t类型,是消息队列的描述符。
在发送和接收消息队列的函数中需要这个描述符来指定是哪个消息队列。
这个值实际是一个整数。
当函数执行出错时,会返回-1.要注意的是,描述符对于不同的进程/线程是不一样的,因此不同的进程/线程不能使用其他进程/线程的描述符。
获取消息队列的属性一个进程在发送和接收消息之前,需要了解消息对象的属性,如消息的最大长度。
以便设定接收和发送的buffer大小。
mqd_t mq_getattr(mqd_t mqdes, struct mq_attr *attr);参数:Mqdes:打开消息队列时获取的描述符。
Attr:指向结构struct mq_attr的指针,用来获取消息队列的四个属性struct mq_attr{long mq_flags; // 0或者O_NONBLOCKlong mq_maxmsg; //队列中包含的消息数的最大限制数long mq_msgsize; //每个消息大小的最大限制数long mq_curmsgs; //当前队列中的消息数}设置消息队列属性我们可以设置消息队列的属性,实际只能设置flag标志,说明队列中没有消息时,接收消息的进程是否在队列上继续等待。
mqd_t mq_setattr(mqd_t mqdes, struct mq_attr *newattr, struct mq_attr *oldattr);参数:Mqdes:打开消息队列时获取的描述符。
Attr:指向结构struct mq_attr的指针,用来获取消息队列的最大消息个数和最大消息长度。
放到数据结构的mq_maxmsg和mq_msgsize中。
struct mq_attr{long mq_flags; // 0或者O_NONBLOCK,只能设置这个long mq_maxmsg; //队列中包含的消息数的最大限制数long mq_msgsize; //每个消息大小的最大限制数long mq_curmsgs; //当前队列中的消息数}oldattr:用来保存设置之前的attr值,可以为NULL.发送消息进程在打开消息队列后,可以使用下面的函数发送消息#include <mqueue.h>int mq_send(mqd_t mqdes, const char *ptr, size_t len, unsigned int prio);参数:mqdes: 打开消息队列时获得的描述符。
ptr: 指向发送缓冲区的指针,发送缓冲区存放了要发送的数据。
Len: 要发送的数据的长度。
prio :消息的优先级;它是一个小于MQ_PRIO_MAX的数,数值越大,优先级越高。
POSIX消息队列在调用mq_receive时总是返回队列中最高优先级的最早消息。
如果消息不需要设定优先级,那么可以在mq_send是置prio为0,mq_receive的prio置为NULL。
返回值:发送成功,返回0,失败,返回-1.接收消息进程在打开消息队列后,可以使用下面的函数接收消息。
ssize_t mq_receive(mqd_t mqdes, char *ptr, size_t len, unsigned int *prio);参数:mqdes: 打开消息队列时获得的描述符。
ptr: 指向接收缓冲区的指针。
接收缓冲区用来存放收到的消息。
Len: 接收缓冲区的长度。
len不能小于mq_msgsize,否则会返回EMSGSIZEprio :消息的优先级;它是一个小于MQ_PRIO_MAX的数,数值越大,优先级越高。
POSIX消息队列在调用mq_receive时总是返回队列中最高优先级的最早消息。
如果消息不需要设定优先级,那么可以在mq_send是置prio为0,mq_receive的prio 置为NULL。
返回值:接收成功,返回0,失败,返回-1.消息队列的关闭mqd_t mq_close(mqd_t mqdes);关闭消息队列,但不能删除它成功返回0,失败返回-1删除消息队列mqd_t mq_unlink(const char *name);成功返回0,失败返回-1当某个进程还没有关闭此消息队列时,调用mq_unlink时,不会马上删除队列,当最后一个进程关闭队列时,该队列被删除例子:下面的例子给出了发送和接收进程中如何创建消息队列,获取消息队列属性,发送消息和接收消息发送进程:创建并发送消息。
#include <mqueue.h>#include <fcntl.h>#include <sys/stat.h>#include <stdio.h>#include <stdlib.h> int main(int argc, char **argv){int flags = 0;mqd_t mqd;flags = O_RDWR | O_CREAT;char *mq_name = (char*)"/MQ_Msg";struct mq_attr attr;long int msgsize = 1024;long int maxmsg = 200;attr.mq_msgsize = msgsize;attr.mq_maxmsg = maxmsg;mqd = mq_open(mq_name, flags, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH, &attr);if (mqd == -1){printf("mq create error\n");return 0;}printf("Create MQ success!\nMax msgs = %ld, Max bytes/msg = %ld\n", attr.mq_maxmsg, attr.mq_msgsize);char msg[1024] = "hello";unsigned int prio = 1;int i;for (i = 0; i < 100; i++){mq_send(mqd, msg, msgsize, prio);}mq_close(mqd);return 0;}接收进程:打开并接收消息#include <unistd.h>#include <fcntl.h>#include <sys/stat.h>#include <stdio.h>#include <stdlib.h> int main(int argc, char **argv){mqd_t mqd;long n;int flags = 0;unsigned int prio = 0;char *buff;struct mq_attr attr;char *mq_name = (char*)"/MQ_Msg";flags = O_RDONLY;mqd = mq_open(mq_name, flags);if (mqd == -1){printf("mq open error\n");return 0;}mq_getattr(mqd, &attr);buff = (char*)malloc(attr.mq_msgsize);while ((n = mq_receive(mqd, buff, attr.mq_msgsize, &prio))){printf("read %ld bytes, msg is %s, priority = %u\n", n, buff, prio);}mq_close(mqd);return 0;}进阶话题:异步事件通知POSIX消息队列可以在空队列收到第一个消息时发送事件通知给需要的进程。