找回密码
 用户注册

QQ登录

只需一步,快速开始

楼主: iq50

关于ACE_WIN32_Proactor代码的一些疑惑

[复制链接]
发表于 2009-6-17 15:37:13 | 显示全部楼层
你理解的和我说的有偏差,你有空看代码的时候,查一下ACE_Proactor_Timer_Handler就清楚了。
对于所有异步事件,都是由workthread处理的。

It also ensures that only one thread is awakened to dispatch the timer since all completion-detection threads wait only for completion events and needn't worry about waking up for a scheduled timer expiration.
他确保只有一个线程是处于激活状态分派定时器事件,因为所有所有完成检测线程(我们所谓的workthread)
仅仅等待事件,这些线程不关心定时器调度的问题。
发表于 2009-6-17 15:47:16 | 显示全部楼层
明白你的意思了。
但是:
这个ACE_Proactor_Timer_Handler由proactor封装起来,貌似没有提供对外操作的接口,
因此我们也没有机会故意阻塞他,所以定时器事件会被proactor很好的被调度。

这个跑Timer Handler的线程,其代码和其他线程的代码是一样的。假如其他线程有机会阻塞,那它也同样有机会阻塞。
另外,有办法得到它的线程id,这样就有办法从外面控制,只让它阻塞。
发表于 2009-6-17 15:58:25 | 显示全部楼层
嗯,当然,想故意搞破坏的办法肯定有很多种啦。
我想说正常的情况proactor可以很好的被调度,
因为没有暴露出多余的接口,
因此可以避免误用导致这个线程的阻塞。
发表于 2009-6-18 14:17:35 | 显示全部楼层
我的意思是:
有一个特殊的线程与众不同。
如果worker thread的代码有可能会在某点阻塞较长时间,注意在这点处让这个特殊的线程例外处理。例如判断自己是否特殊线程,如是则交给别人做。
否则可能延误对timer事件的处理。

其实我们说的没矛盾,我也同意多线程跑proactor,即使同时处理timer event也没问题。只是提醒一下这一点特别之处需要注意。
发表于 2009-6-18 16:32:03 | 显示全部楼层
// Set the timer queue.
  this->timer_queue (tq);

  // Create the timer handler
  ACE_NEW (this->timer_handler_,
           ACE_Proactor_Timer_Handler (*this));

  // Activate <timer_handler>.
  if (this->timer_handler_->activate () == -1)
    ACE_ERROR ((LM_ERROR,
                ACE_TEXT ("%N:%l:(%P | %t):%p\n"),
                ACE_TEXT ("Task::activate:could not create thread\n")));
这是proactor构造函数内的代码,可以看出ACE_Proactor_Timer_Handler 是继承自ACE_Task的,
在svc方法内部仅作检查超时,检查到超时之后调用this->proactor_.timer_queue ()->expire ();
不做其他任何事情。

timer_queue 的定义为:
typedef ACE_Timer_Queue_T<ACE_Handler *,
                            ACE_Proactor_Handle_Timeout_Upcall,
                            ACE_SYNCH_RECURSIVE_MUTEX>
  TIMER_QUEUE;

因此其实expire 的内部调用了ACE_Proactor_Handle_Timeout_Upcall的timeout方法
在timeout函数内部,创建了一个ACE_Asynch_Result_Impl,然后调用PostQueuedCompletionStatus
将这个事件推人完成端口。

然后任意我们被激活的工作线程,将通过GetQueuedCompletionStatus获得这个完成事件,
并在自定义的handle_time_out内部被处理。这就是全部的过程了。

工作线程即是工作线程,timer调度线程即是调度线程,两者不存在包含关系,
因此无需判断自己是否是特殊线程,其他的部分,我们的理解是一致的。
发表于 2009-6-19 13:35:38 | 显示全部楼层
汗。。误会了,我的意思是处理handle_time_out的那个线程是特殊线程,不是post timer expire event的那个线程。
昨晚回去看了下以前跑的例子,发现我犯了个大错,晕。。
事实上所有worker thread都可以处理handle_time_out,没有特殊线程。
以前跑的example里的test_multiple_loops.cpp,是wfmo reactor + proactor的,对于wfmo reactor处理timer,只有一个owner线程才能处理handle_time_out,但这个owner属性可以在运行期修改。
我把它和proactor搞混了。
发表于 2009-6-19 14:00:19 | 显示全部楼层
Reactor和Proactor,那是大大的不同呀。。。
发表于 2009-6-19 14:36:24 | 显示全部楼层
哈哈,主要是ACE太复杂了,很多细节过段时间就记不清了。
那个例子是reactor和proactor混合的,可以跑各种组合情况。只记得timer event比较奇怪,某种情况下只被一个特定线程处理。这次看到proactor的说明里好像也有类似说法,就搞混了。:lol
发表于 2009-6-19 15:19:50 | 显示全部楼层
这个主题的长度也创了记录了。
我之所以研究、应用ACE系统,就是因为它是集大成者。营养简直吸收不完。
发表于 2009-6-20 13:13:55 | 显示全部楼层
是啊,不过可惜国内学和用ACE的太少了。有时候感到很孤独,能找个人交流下ACE是件很难得很奢侈的事情。
老大维护这个论坛,尽管人气不高,但是一直坚持着为大家提供服务,实在是用心良苦。
您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

Archiver|手机版|小黑屋|ACE Developer ( 京ICP备06055248号 )

GMT+8, 2024-11-23 03:57 , Processed in 0.020892 second(s), 5 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表