QNX----知识 频道(Channel)与连接(Connect)

QNX频道的概念 :

 频道(Channel)与连接(Connect) 

消息传递是基于服务器与客户端的模式来进行的,那么客户端怎样才能与服务器端通讯呢?最简单的,当然是指定对方的进程号。要发送的一方,将消息加一个头,告诉内核“把这个消息发给pid 12345”就行了。其实这也是QNX4时候的做法。但QNX6开始完整支持POSIX线程后,这种方法似乎就不太适合了。如果服务器,有两个线程,分别进行不同的服务,那该怎么办呢?或者你会说“把这个消息发给pid 12345 tid 3”就行了。可是,如果某一个服务,不是由单一线程来进行服务的,而是有一组线程进行的,那又怎么办呢?为此,QNX6抽象出了”频道“(Channel)这个概念。一个频道,就是一个服务的入口;至于这个频道到底具体有多少线程为其服务,那都是服务器端自己的事情。一个服务器如果有多个服务,它也可以开多个频道。而客户端,在向“频道”发送消息前,需要先建立连接(Connection),然后将消息在连接上发出去。这样同一个客户端,如果需要,可以与同一个频道建立多个连接。 

服务器

 

代码: 全选

     ChannelId = ChannelCreate(Flags);
  • 1

客户端

代码: 全选

     ConnectionId = ConnectAttach(Node, Pid, Chid, Index, Flag);
  • 1

 

Node:是机器号,如果存在网络分布处理,这个值将决定那台机器;如果服务器和客户端在同一个板子里,就是0。

PID:进程编号;

CHID:频道号;

常用API函数

extern int ChannelCreate(unsigned __flags);
extern int ChannelCreate_r(unsigned __flags);
extern int ChannelCreateExt(unsigned __flags, mode_t __mode, size_t __bufsize, unsigned __maxnumbuf, const struct sigevent *__ev, struct _cred_info *__cred);
extern int ChannelDestroy(int __chid);
extern int ChannelDestroy_r(int __chid);
extern int ConnectAttach(_Uint32t __nd, pid_t __pid, int __chid, unsigned __index, int __flags);
extern int ConnectAttach_r(_Uint32t __nd, pid_t __pid, int __chid, unsigned __index, int __flags);

extern int ConnectAttachExt(_Uint32t __nd, pid_t __pid, int __chid, unsigned __index, int __flags, struct _asyncmsg_connection_descriptor *__cd);
extern int ConnectDetach(int __coid);

extern int ConnectDetach_r(int __coid);

extern int MsgReceive(int __chid, void *__msg, int __bytes, struct _msg_info *__info);

extern int MsgReceive_r(int __chid, void *__msg, int __bytes, struct _msg_info *__info);

extern int MsgReply(int __rcvid, int __status, const void *__msg, int __bytes);

extern int MsgReply_r(int __rcvid, int __status, const void *__msg, int __bytes);

extern int MsgRead(int __rcvid, void *__msg, int __bytes, int __offset);
extern int MsgRead_r(int __rcvid, void *__msg, int __bytes, int __offset);

连接的终止是ConnectDetach(),而频道的结束则是ChannelDestroy()了。不过,一般服务器都是长久存在的,不大有需要ChannelDestroy()的时候。

发送(Send),接收(Receive)和应答(Reply) 
QNX的消息传递,与我们传统常见的进程间通讯最大的不同,就是这是一个"同步的"消息传递。一个消息传递,都要经过发送,接收和应答三个部份,所谓的 SRR过程。具体来说,客户端在连接上"发送"消息,一旦发送,客户端会被阻塞,服务器端会接收到消息,进行处理,最后,将处理结果"应答"给客户端;只有服务器"应答"了以后,客户端的阻塞状态才会被解除。这种同步的过程,不但保证的客户端与服务器端的时序,也大大简化了编程。具体用API来说,就是这样。 

 

 

 

#include

#include
#include
#include
#include
#include
 
#define MY_PULSE_CODE   _PULSE_CODE_MINAVAIL


typedef union {
        struct _pulse   pulse;
        /* your other message structures would go
           here too */
} my_message_t;


int main(int argc, char *argv[])
{
   struct sigevent         event;
   struct itimerspec       itime;
   timer_t                 timer_id;
   int                     chid;
   int                     rcvid;
   my_message_t            msg;

 
   chid = ChannelCreate(0);/*创建通道*/


   event.sigev_notify = SIGEV_PULSE;
   event.sigev_coid = ConnectAttach(ND_LOCAL_NODE, 0,
                                    chid,
                                    _NTO_SIDE_CHANNEL, 0);
   event.sigev_priority = getprio(0);
   event.sigev_code = MY_PULSE_CODE;
   timer_create(CLOCK_REALTIME, &event, &timer_id);
    /*it_value 设定的是第一次初始化值*/
   itime.it_value.tv_sec =1;
   /* 500 million nsecs = .5 secs */
   itime.it_value.tv_nsec = 500000000;
   /*it_interval 设定的是每次间隔值*/
   itime.it_interval.tv_sec = 0;
   /* 500 million nsecs = .5 secs */
   itime.it_interval.tv_nsec = 100000000;
   timer_settime(timer_id, 0, &itime, NULL);


   /*
    * As of the timer_settime(), we will receive our pulse
    * in 1.5 seconds (the itime.it_value) and every 1.5
    * seconds thereafter (the itime.it_interval)
    */


   for (;;) {
       rcvid = MsgReceive(chid, &msg, sizeof(msg), NULL);
       if (rcvid == 0) { /* we got a pulse */
            if (msg.pulse.code == MY_PULSE_CODE) {
                printf("we got a pulse from our timer\n");
            } /* else other pulses ... */
       } /* else other messages ... */
   }
}

你可能感兴趣的:(QNX系统与驱动)