Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1563862
  • 博文数量: 237
  • 博客积分: 5139
  • 博客等级: 大校
  • 技术积分: 2751
  • 用 户 组: 普通用户
  • 注册时间: 2008-11-18 14:48
文章分类

全部博文(237)

文章存档

2016年(1)

2012年(4)

2011年(120)

2010年(36)

2009年(64)

2008年(12)

分类: C/C++

2009-11-20 13:35:55

Creates a Rendezvous request with the thread.
The request is an asynchronous request, and completes:
when the thread next calls RThread::Rendezvous(TInt aReason)
if the outstanding request is cancelled by a call to RThread::RendezvousCancel()
if the thread exits
if the thread panics.
Note that a request requires memory to be allocated; if this is unavailable, then this call to Rendezvous() returns, and the asynchronous request completes immediately.

Rendezvous是线程之间通信主要用作同步的一种方法,主要用作同步而不是数据交换。一个线程中
的活动对象可以用这种方法确定目标线程已经运行到一个特定的阶段或者状态。相对
于其它 IPC 方式来说,适用的场景比较少(很少用到) :)

比如线程 A 的某个活动对象调用:
IMPORT_C void Rendezvous(TRequestStatus &aStatus) const;  //非静态方法
请求在线程 B 运行到一个固定的集合点的时候得到通知。

当线程 B 运行到特定阶段的时候,线程 B 调用(注意,这是个静态方法):
static IMPORT_C void Rendezvous(TInt aReason);            //静态方法
通知操作系统,已经达到这个集合点。操作系统会通知线程 A,进入活动对象的RunL。

Symbian 给的一个最有说服力的例子就是服务器的实现。服务器主线程需要在服务线
程成功启动并完成特定的任务(比如初始化)之后执行后续操作。

服务器主线程在创建服务线程之后,调用:
// 请求得到服务线程调用 Rendezvous(TInt) 的通知
serviceThread.Rendezvous(oneStatus);
// 开始执行服务线程
// 注意这里一定是首先调用 Rendezvous,然后 Resume
serviceThread.Resume();

然后在服务线程里,执行完规定的操作之后就可以调用:
// 通知主线程初始化或者预订任务完成
RThread::Rendezvous(KErrNone);

如果你熟悉 windows 的 event 的话,它类似有只有 pusle 模式的 event。这个 event 只
有目标线程能激活,另外在目标线程退出的时候能被自动激活。

另外一个可能使用的场景是执行 long term task。在 AO 的教程里面有一种切分任务
的方法。这种方法比较繁琐。你可以创建一个子线程来执行这个 long term task(主
线程是 UI 部)。在执行之前,请求子线程的集合点。如果子线程正常退出,或者调
用 Rendezvous 报告已经完成操作,你的 UI 线程得到通知后就可以执行后续操作。
如果那个任务线程不重复使用的话,也可以通过 Logon 实现。如果重复使用的话,
使用 server-client 结构可能更合适一些 :P

这个函数在进程里也有,用法也类似,适用的场景也一样少。

*********************************************************************
是同步用的。比较弱的同步方法,但是很特别,而且有一点别的同步方法做不到:
即使目标线程没有明确的调用 Rendezvous 发送通知,在目标线程退出(无论正常
还是异常)的时候,监听的活动对象都能得到消息。

举个例子,比如你要执行一个旅行任务,行程是"北京-深圳-香港-上海"。如果有几
个人(一个或者多个),对你到了"深圳"感兴趣。他们在你的线程上注册事件。然
后你们约好等你到"深圳"的时候,你大吼一声"我到深圳了",这些活动对象都会得
到通知。这就是一个"集合点"。

如果它们对你的下一站"香港"也感兴趣,并且又做了注册。你们约好等你到香港的
时候再大吼一声"我到香港了"。这又是一个集合点。集合点是双方约定的,但是是
在你的线程里实现的,你如果不喊,大家就只能等你因为某种原因结束线程了。

还有一个问题,如果我想知道你什么时候到"深圳",可是注册的时候你已经走过了,
我就只能听到你喊"我到香港了"...我只能要求你"到的时候告诉我",不能告诉你"
到深圳的时候告诉我",或者"到香港的时候告诉我"。

对于多个集合点来说,我个人觉得复杂而且容易出错。如果真能吼出来"香港","深
证"这样的话也好,但是 Rendezvous 只能吼一个整数,就是参数里的那个 reason。
而这个整数同时又是用来表示各种错误码的,呵呵。

单个集合点的话,服务器就是很好的例子。

Rendezvous 优点是:即使你选择一路沉默,一声不吭,我只要注册了就能知道你最
后是成功走完了还是中途退出了。这是由操作系统保证的。
if the thread exits
if the thread panics.
这两句话说的就是这个意思。

可以同时有多个活动对象在一个集合点上进行注册。
阅读(1830) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~