浏览 14329 次
精华帖 (0) :: 良好帖 (3) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2010-04-22
地址:http://blog.csdn.net/haoel/archive/2008/05/04/2379586.aspx 作者:chenhao 里面的观点我不关心,但是刚好我看到selector.wakeup()这个功能我们自己的程序里也在使用. 我们程序的逻辑基本是这样(server): 处理完请求之后需要发回执.这个时候就把 session 对象(session里包含单独用户的socketchannel)丢回 socketlistener 的队列.然后触发socketlistener里面的selector.wakeup()方法. 也就是:每当有回执包需要发送给客户端的时候就把selector.wakeup()执行一次. 除此之外,还有退出侦听的时候也执行了selector.wakeup: public final synchronized void exit() { this.readORwrite = false; this.selector.wakeup(); } =============================================================== 我仔细看了那个文章的回帖.其中一贴: 引用 不是一直保持一个loopback connection,而是需要的时候才发起一个loopback connection。我能想到的需要的时候就只有一个,就是程序结束了,要让select“优雅”的关闭。为了一个只在整个程序生命周期使用不到万分之1的功能花费一个链接资源的话不是很值得
那么,这是否证明我们这个程序书写有问题呢? 我们这个程序在每次有回执包产生的时候都要调用一次selector.wakeup(); 这样是否影响我们程序的效率? 还有,selector.wakeup();这个东西到底有什么用呢?我还是比较模糊. 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2010-04-22
最后修改:2010-04-22
selector.wakeup主要是为了唤醒阻塞在selector.select上的线程,让该线程及时去处理其他事情,例如注册channel,改变interestOps、判断超时等等。
selector的实现其实跟大多数跨平台的网络框架的实现没有两样,如果你了解过ACE框架的话,也会发现它也是在windows上使用loopback connection来实现notify的机制。 从你的描述来看,你们的用法没错,及时唤醒selector去处理写,这个没有问题。频繁的wakeup是对性能有影响,因此这里可以做个优化,在将session对象加入队列之前,你可以判断队列是否为空,为空的时候才在加入队列后去唤醒select阻塞的线程处理队列里的数据,避免在队列有数据的时候重复唤醒。也就是类似这样的代码: boolean needsWakeup=false; synchronized(queue) { if(queue.isEmpty()) needsWakeup=true; queue.add(session); } if(needsWakeup) selector.wakeup(); 在Mina 2.0里的优化是通过一个原子变量 private final AtomicBoolean wakenUp = new AtomicBoolean(false); 在select之前将wakenUp设置为false, wakenUp.set(false); selector.select(timeout); …… 那么在wakeup方法调用之前通过cas来避免重复的唤醒: if (this.wakenUp.compareAndSet(false, true)) { selector.wakeup(); } |
|
返回顶楼 | |
发表时间:2010-04-22
通过pipe写数据来唤醒线程,这在linux平台编程上是很常见的技巧,如memcached的多线程实现也是这样的,只不过因为windows平台没有pipe的支持,才使用一个tcp的loopack connection,因此会显得比较怪异。
|
|
返回顶楼 | |
发表时间:2010-04-22
感谢楼上,我知道怎么优化了.
|
|
返回顶楼 | |
发表时间:2010-04-22
dennis_zane 写道 通过pipe写数据来唤醒线程,这在linux平台编程上是很常见的技巧,如memcached的多线程实现也是这样的,只不过因为windows平台没有pipe的支持,才使用一个tcp的loopack connection,因此会显得比较怪异。
win下面 其实也有pipe..只是不怎么好用... |
|
返回顶楼 | |
发表时间:2010-04-22
mathgl 写道 dennis_zane 写道 通过pipe写数据来唤醒线程,这在linux平台编程上是很常见的技巧,如memcached的多线程实现也是这样的,只不过因为windows平台没有pipe的支持,才使用一个tcp的loopack connection,因此会显得比较怪异。
win下面 其实也有pipe..只是不怎么好用... 恩,主要还是windows上的pipe不能放入select的fd_set |
|
返回顶楼 | |