P2psim源代码分析四
来源:互联网 发布:win10 正在准备windows 编辑:程序博客网 时间:2024/05/18 00:59
P2psim源代码分析四
Kejieleung
Channel与RPC
这次重点分析Channel与RPC。Channel作为底层task的数据通道,用于传输task之间的数据。channel结点定义为(注意在定义task.h里,还有相关的操作):
struct Channel
{
unsigned int bufsize;
unsigned int elemsize;
unsigned char *buf;
unsigned int nbuf;
unsigned int off;
Altarray asend;
Altarray arecv;
char *name;
};
在Packet、RPCHandle、Network、EventQueue里都有使用到.
EventQueue的构造函数如下: EventQueue::EventQueue() : _time(0) { //kejie: Channel *_gochan; _gochan = chancreate(sizeof(Event*), 0); assert(_gochan); //kejie:add self run to the threadmanage thread(); } 之后再通过EventQueue::run()线程函数时调用 recvp(_gochan) 接收底层task发送到channel的数据。详细的实现可以进一步看看task里的定义,不过反正这部分不是重点,只要了解一下就可以。 一般意义的RPC使用client/server模型。请求程序是client,而服务提供程序则为server。就像一般的本地过程调用一样,且RPC是一个同步操作,直到远程过程结果返回请求程序才可以挂起。在P2PSim里的RPC机制在是单机里的模拟。通过底层的channel来传递请求。先看看RPCHandle的定义: class RPCHandle { public: RPCHandle(Channel*, Packet*); ~RPCHandle(); Channel *channel() { return _c; } Packet *packet() { return _p; } private: Channel* _c; Packet* _p; }; 定义很简单,主要是看用法和相关操作,集中在Node.h里使用,且多数操作是以模板形式,还用到了成员函数指针,所以看起来比较费劲呵呵,不过没关系,慢慢来。关于Node类的详细分析留在下一章进行,这里先抽出RPC相关操作与数据结构。 相关操作有: // Send an RPC from a Node on one Node to a method // of the same Node sub-class with a different ip template<class BT, class AT, class RT> bool doRPC(IPAddress dst, void (BT::* fn)(AT *, RT *), AT *args, RT *ret, Time timeout = 0) // Same as doRPC, but this one is asynchronous template<class BT, class AT, class RT> unsigned asyncRPC(IPAddress dst, void (BT::* fn)(AT *, RT *), AT *args, RT *ret, Time timeout = 0, unsigned token = 0) // returns one of the RPCHandle's for which a reply has arrived. BLOCKING.( Used in asyncRPC) unsigned rcvRPC(RPCSet*, bool&); void _deleteRPC(unsigned); typedef set<unsigned> RPCSet; HashMap<unsigned, RPCHandle*> _rpcmap; // RPC machinery template<class BT, class AT, class RT> class Thunk bool _doRPC(IPAddress, void (*fn)(void *), void *args, Time timeout = 0); RPCHandle* _doRPC_send(IPAddress, void (*)(void *), void (*)(void*), void *, Time = 0); bool _doRPC_receive(RPCHandle*); // creates a Thunk object with the necessary croft for an RPC //kejie: Node::Thunk<BT, AT, RT> * 为返回值 template<class BT, class AT, class RT> Node::Thunk<BT, AT, RT> * _makeThunk(IPAddress dst, BT *target, void (BT::*fn)(AT*, RT*),AT *args, RT *ret) 具体的实现都在Node.h里,由于部分模板函数比较复杂,等到具体协议实现时再回过头来分析,这里先放一下,只分析一下recvRPC析流程。 recvRPC用于返回一个已有回应到达的RPCHandle,注释里说是一个阻塞操作,理解为有立即返回结果即可: (1) 根据hset里标识的索引,在_rpcmap里找出要接收信息的channel信息,记录在Alt数组里 Alt定义为(task.h): struct Alt { Channel *c; void *v; unsigned int op; Task *task; Alt *xalt; }; 注意还有一个alt是定义为 #define alt chanalt int chanalt(Alt *alts); (2) 传入alt(a)->[ chanalt(Alt*a) ] 处理执行 (3) 在alt中,首先要确定传入的alt的长度,设定为taskrunning (4) 检查每个a[i]是否可运行,记录可运行的数目,如果多于一个就随机选择一个 (5) 确认是否有数据返回,再删除索引 详细代码如下:
整体的RPC操作可以参考以下UML图,再对照源代码:
(由于暂时上传不了图片,以后再补上)
也可以留下E-mail我将word版本传过去哈~~~最好直接发到我的邮箱因为有时没上空间也不知道呢呵呵~~
kejieleung@163.com
- P2psim源代码分析四
- P2psim 源代码分析(一)
- P2psim 源代码分析二
- P2psim源代码分析三
- P2psim源代码分析五
- MTD源代码分析(四)
- eMule源代码分析(四)
- Iperf 源代码分析(四)
- WebKit 内核源代码分析 ( 四 )
- WebKit 内核源代码分析 ( 四 )
- WebKit 内核源代码分析 ( 四 )
- Iperf 源代码分析(四)
- WebKit 内核源代码分析 ( 四 )
- WebKit 内核源代码分析 ( 四 )
- WebKit 内核源代码分析 ( 四 )
- WebKit 内核源代码分析(四)
- Gzip源代码分析(四)
- WebKit 内核源代码分析 ( 四 )
- OpenSSH安全(from FreeBSD 使用手册)
- devices 命令改变默认sdk
- java(web)中的相对路径和绝对路径
- C语言下打印调用栈
- 第一次CSDN博客
- P2psim源代码分析四
- NUnit2.0详细使用方法
- 小型软件公司的绩效考核
- C#开发和使用中的23个技巧
- 八皇后问题的位操作解法
- ASP.NET中常用的26个优化性能方法
- asp.net中将各种视频文件转换成.flv格式
- C#中的cookie编程
- JSP活动头像上传