【Qnx 】Qnx IPC通信PPS

Qnx IPC通信PPS

Qnx自带PPS服务,PPS全称Persistent Publish/Subscribe Service,就是常见的P/S通信模式。
Qnx PPS的通信模式是异步的,Publisher和Subscriber也无需关心对方是否存在。

利用Qnx提供的PPS服务,Publisher可以通知多个Subscriber进行某种动作。
该图是QNX官网的PPS示例场景。

  • Applications和组件(比如Media、Radio、Phone等等)通过PPS交互消息。
    在这里插入图片描述
    官网链接:
    http://www.qnx.com/developers/docs/7.1/index.html#com.qnx.doc.pps.developer/topic/about.html

使用QNX PPS

Qnx 的PPS,是利用文件的方式实现的。所以使用起来,跟文件的读写差不多。

  • Publisher端打开文件,写入文件。
int fd = open( "/pps/example/button", O_RDWR | O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO );

ssize_t len, bytes_written;
len = snprintf(buf, 256, "state::%s\npub1::%d", state ? "on" : "off", count);
bytes_written = write( fd, buf, len );
  • Subscriber打开文件,监听文件描述符产生的写入事件,监听可以使用epoll、select、ionotify(qnx提供)等等。
  • 打开文件时“?”后面表示打开模式。delta表示增量模式,所谓增量模式,每次只读取PPS数据中变更的部分。
int fd = open( "/pps/example/button?delta", O_RDONLY );
struct pollfd readfds[1];
 

 while (1) {
    readfds[0].fd = fd;
    readfds[0].events = POLLIN;
    
    int result = poll(readfds, 1, timeout);
    if(result != -1 && result != 0) {
        if( readfds[0].revents & POLLRDNORM ){
               // 也可以选择其他读取方式
               // 利用fd的读文件方式有很多种
               num_bytes = read( fd, buf, sizeof(buf) );
               if (num_bytes > 0) {
                   // 解析数据
               }
        }
    } 
 }
  • Publisher打开(不存在的时候创建)PPS服务路径下(默认为/pps,可配置)的文件,往文件里写入数据。Subscriber打开要监听的文件(与Publisher一个文件),监听该文件的写入事件,当写入时读取该文件,即可。

完整的例子(QNX官网提供)

  • Publisher
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>

int main(int argc, char *argv[])
{
   int fd;
   int state = 0;
   char buf[256];
   struct stat stat_buf;
   int count = 0;
   ssize_t len, bytes_written;

   /* Is PPS running? */
   if (stat( "/pps", &stat_buf) != 0)
   {
      if (errno == ENOENT)
         printf ("The PPS server isn't running.\n");
      else
         perror ("stat (/pps)");
      return EXIT_FAILURE;
   }

   /* Create the "button" object (if it doesn't already exist). */
   fd = open( "/pps/example/button", O_RDWR | O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO );
   if ( fd < 0 )
   {
      perror ("Couldn't open /pps/example/button");
      return EXIT_FAILURE;
   }

   /* Loop forever, toggling the state of the button. */
   while ( 1 )
   {
      usleep (500);
      count++;
      len = snprintf(buf, 256, "state::%s\npub1::%d", state ? "on" : "off", count);
      bytes_written = write( fd, buf, len );
      if (bytes_written == -1)
      {
         perror ("write()");
      }
      else if (bytes_written != len)
      {
         printf ("Bytes written: %d String length: %d\n", bytes_written, len);
      }

      if ( state == 0 )
         state = 1;
      else
         state = 0;
   }

   return EXIT_SUCCESS;
}
  • Subscriber
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <sys/poll.h>

int main(int argc, char *argv[])
{
   int fd;
   char buf[256];
   ssize_t num_bytes;
   int ret;
   struct pollfd readfds[1];
   int timeout = 2000;

   fd = open( "/pps/example/button?delta", O_RDONLY );
   if ( fd < 0 )
   {
      perror ("Couldn't open /pps/example/button");
      return EXIT_FAILURE;
   }

   /* Loop, echoing the attributes of the button. */
   while (1)
   {
      readfds[0].fd = fd;
      readfds[0].events = POLLIN;

      switch ( ret = poll(readfds, 1, timeout ) )
      {
         case -1:
            /* An error occurred. */
            break;
         case  0:
            /* poll() timed out. */
            break;
         default:
            if( readfds[0].revents & POLLRDNORM )
            {
               num_bytes = read( fd, buf, sizeof(buf) );
               if (num_bytes > 0)
               {
                  write (STDOUT_FILENO, buf, (size_t) num_bytes);
               }
            }
      }
   }

   return EXIT_SUCCESS;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

林多

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值