各模块(进程)之间,采用消息队列的方式通信。整体通信采用一个调度转接点,其他进程只和这一个转接点进程进行通信的方式进行, 如果发给其他进程的消息,也通过调度进程进行转发, 调度进程起名字叫Dispatch Process。
在dispatch程序刚启动时,需要对消息队列进行初始化,因为它是中转进程,需要和所有进程建立消息队列。
dispatch_mqfd = mq_open("/mq_dispatch", O_RDWR|O_CREAT|O_NONBLOCK, 0666, ), 最大数目8个,消息size 512
proca_mqfd = mq_open("/mq_procA", O_RDWR|O_CREAT|O_NONBLOCK, 0666, ), procB, procC。
在其他进程中,如果只发不收,只打开dispatch mq就可以, 如果还要收消息,就要打开并监听自己的mq:
dispatch_mqfd = mq_open("/mq_dispatch", O_RDWR|O_CREAT|O_NONBLOCK, 0666, ), 最大数目8个,消息size 512
proca_mqfd = mq_open("/mq_procA", O_RDWR|O_CREAT|O_NONBLOCK, 0666, )。
消息头数据结构
{dstMq, srcModule, Operation, msgLen}
对于往外发消息,都发给dstMq=MQ_DISPATCH, srcModule=MQ_PROCA, 指定做什么,后面跟的消息长度是多少。
mq_send(dispatch_mqfd, buffer, len, 1);
收消息, 在dispatch进程中有专门检测mq的线程:
select(1+dispatch_mqfd , &fdset, 0, 0 , NULL)
if(FD_ISSET(dispatch_mqfd, &fdset)) mq_receive(dispatch_mqfd, buffer, MAX_MSG_LEN,0)
对buffer取 header长度,解析头,解析Operation, 执行相应的操作。
执行完后, 开始对过来消息的dstMq进行判断, 如果是发给Dispathc自己的,就退回,如果是发给别人的,再把这条消息,发送出去。
if dstMq & PROCB, mq_send(procB_mqfd, buffer, len, 1)。同样的,procB,也会有一个线程在监听procB_mqfd, 如果有消息,过来,同样是解析出Operation, 做具体的操作。
这样, 所有的消息都会发到Disaptch, 监测如果是自己要处理的,就直接处理,然后看dstMq是不是还要发给别人, 就再次转发给对应的mqfd, 就完成了所有模块之间的通信。