Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1816982
  • 博文数量: 496
  • 博客积分: 12043
  • 博客等级: 上将
  • 技术积分: 4778
  • 用 户 组: 普通用户
  • 注册时间: 2010-11-27 14:26
文章分类

全部博文(496)

文章存档

2014年(8)

2013年(4)

2012年(181)

2011年(303)

2010年(3)

分类: C/C++

2011-01-10 19:01:22

设计并实现了一个用于进程间通讯的对象。在实际使用中,进程间通讯可以细分为远程方法调用和远程事件。类似于前面所讲的对象系统中的方法和事件。远程事件 的例子比如说系统中有A,B,C三个进程对u盘热插拔的事件感兴趣,但是不可能三个进程都去监视系统的u盘事件,因为直接去获取和过滤系统事件可能比较复 杂(比如目前linux是通过udev写过滤器和udev事件接收程序)。可以专门写一个S程序来获取和过滤系统事件,然后触发一个远程事件发给 A,B,C。远程方法的例子还是可以这个例子,有时候A进程可能想主动的向B查询一下当前的u盘设备。这时A就调用B的远程方法,并取回B的返回值。

      也就是说远程事件是1对多,是被动接收的,没有返回值。并且A,B,C三者都需要先告诉S对什么事件感兴趣,这样S才知道事件发给谁。远程方法是1对1的,就是主动调用并要取回返回值。远程事件和方法是独立的,可以有也可以没有互相没有关系。

typedef DINT (*Gd_Remote_Method_Function)(void *msg_obj, GD_ID method, GD_TABLE *in_out, void *arg, GD_EXIST *exist); 远程方法的执行函数原型

typedef void (*Gd_Remote_Method_Return_Function)(void *msg_obj, GD_ID method, GD_TABLE *out, void *arg, DINT ret, GD_EXIST *exist); 接收远程方法返回值的回调函数原型

void *GdMessageCreate(char *name, Gd_Remote_Method_Function func, void *arg);创建一个远程消息通讯的对象,提供一个name,这个name是整个系统唯一的,如果已经存在相同名字的会创建不成功。提供一个远程方法的执 行函数,这样其他进程才可以远程执行你的方法,如果你不提供别人调用的远程方法,这个参数为NULL,最后一个参数arg会复制给你的func中的参数 arg.

DINT GdMessageRegisterRemoteEvent(void *msg_obj, char *remote, GD_ID event, Gd_Event_Function func, void *arg);该函数告诉远程的remote,我对你的event事件感兴趣,并且如果以后remote触发了该事件,回调执行我提供的函数func, arg会复制到func中的参数arg。

void GdMessageTriggerRemoteEvent(void *msg_obj, GD_ID event, GD_TABLE *in);触发远程事件,所有对msg_obj的event事件感兴趣的其他进程都会收到该事件调用相应的回调函数。参数in这个GD_TABLE也会原 封不动的传递给其他进程的回调函数。比如上面的例子,当S检测到系统有u盘插入时,就执行GdMessageTriggerRemoteEvent(S, GD_STIRNG_ID(u_hotplug), NULL);

void GdMessageDeleteRemoteEvent(void *msg_obj, char *remote, GD_ID event);告诉remote,我对你的event事件不感兴趣了。

DINT GdMessageRemoteMethod(void *msg_obj, char *remote, GD_ID method, GD_TABLE *in, Gd_Remote_Method_Return_Function func, void *arg);执行remote的远程方法,参数in会原封不动的传递给remote的方法执行函数Gd_Remote_Method_Function. 因为是远程方法,没有阻塞等待远程方法的返回结果. 该函数发包后就立即返回,所以用户还要提供一个Gd_Remote_Method_Return_Function func,在以后收到返回结果时会回调这个函数。

void GdMessageIgnoreRemoteReturn(void *msg_obj, char *remote, GD_ID method);忽略remote的远程方法返回结果。

const char *GdMessageGetRemote(void *msg_obj);在各种回调函数中调用该函数的到此时相应的远程进程的名字。

该进程间通讯对象的设计是p2p的,即每个进程的地位都是一样的,都可以既做client又做server,当然在实际使用中大多是一种身份。下面是一个简单的例子:

client:

void remote_method_return(void *msg_obj, GD_ID method, GD_TABLE *out, void *arg, DINT ret, GD_EXIST *exist)

{

printf("server method2 return %d, the table from remote is\n", ret);

GdTableDump(out);

return;

}

main()

{

void *client;

client = GdMessageCreate(GD_STRING_ID(client), NULL, NULL);

GdMessageRemoteMethod(client, "server", GD_STRING_ID(method1), NULL, NULL, NULL);

GdMessageRemoteMethod(client, "server", GD_STRING_ID(method2), NULL, remote_method_return, NULL);

while(1) GdTaskLoopOnce(0);

}

server:

void remote_method(void *msg_obj, GD_ID method, GD_TABLE *in_out, void *arg, GD_EXIST *exist)

{

if(method == GD_STRING_ID(method1))

printf("server got method1\n");

else if(method == GD_STRING_ID(method2))

printf("server got method2\n");

return;

}

main()

{

void *server;

server = GdMessageCreate(GD_STRING_ID(sever), NULL, NULL);

while(1) GdTaskLoopOnce(0);

}

阅读(1055) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~