`
nada_forever
  • 浏览: 24861 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

【转】Selector.wakeup实现注记

阅读更多

版权信息:

原文地址:http://www.blogjava.net/killme2008/archive/2010/10/22/335861.html

原文作者:dennis.zane

 

 

NIO中的Selector封装了底层的系统调用,其中wakeup用于唤醒阻塞在select方法上的线程,它的实现很简单,在linux上就是创建一个管道并加入poll的fd集合,wakeup就是往管道里写一个字节,那么阻塞的poll方法有数据可读就立即返回。证明这一点很简单,strace即可知道:

 

public class SelectorTest {
    
public static void main(String[] args) throws Exception {
        Selector selector 
= Selector.open();
        selector.wakeup();
    }
}


     使用strace调用,只关心write的系统调用

sudo strace --e write java SelectorTest


     输出:

Process 29181 attached
Process 
29182 attached
Process 
29183 attached
Process 
29184 attached
Process 
29185 attached
Process 
29186 attached
Process 
29187 attached
Process 
29188 attached
Process 
29189 attached
Process 
29190 attached
Process 
29191 attached
[pid 
29181] write(36"\1"1)          = 1
Process 
29191 detached
Process 
29184 detached
Process 
29181 detached


    有的同学说了,怎么证明这个write是wakeup方法调用的,而不是其他方法呢,这个很好证明,我们多调用几次:

public class SelectorTest {
    
public static void main(String[] args) throws Exception {
        Selector selector 
= Selector.open();
        selector.wakeup();
        selector.selectNow();
        selector.wakeup();
        selector.selectNow();
        selector.wakeup();
    }
}


    修改程序调用三次wakeup,心细的朋友肯定注意到我们还调用了两次selectNow,这是因为在两次成功的select方法之间调用wakeup多次都只算做一次,为了显示3次write,这里就每次调用前select一下将前一次写入的字节读到,同样执行上面的strace调用,输出:

Process 29303 attached
Process 
29304 attached
Process 
29305 attached
Process 
29306 attached
Process 
29307 attached
Process 
29308 attached
Process 
29309 attached
Process 
29310 attached
Process 
29311 attached
Process 
29312 attached
Process 
29313 attached
[pid 
29303] write(36"\1"1)          = 1
[pid 
29303] write(36"\1"1)          = 1
[pid 
29303] write(36"\1"1)          = 1
Process 
29313 detached
Process 
29309 detached
Process 
29306 detached
Process 
29303 detached


     果然是3次write的系统调用,都是写入一个字节,如果我们去掉selectNow,那么三次wakeup还是等于一次:

public class SelectorTest {
    
public static void main(String[] args) throws Exception {
        Selector selector 
= Selector.open();
        selector.wakeup();
        selector.wakeup();
        selector.wakeup();
    }
}

  
   输出:

Process 29331 attached
Process 
29332 attached
Process 
29333 attached
Process 
29334 attached
Process 
29335 attached
Process 
29336 attached
Process 
29337 attached
Process 
29338 attached
Process 
29339 attached
Process 
29340 attached
Process 
29341 attached
[pid 
29331] write(36"\1"1)          = 1
Process 
29341 detached
Process 
29337 detached
Process 
29334 detached
Process 
29331 detached


      wakeup方法的API说明没有欺骗我们。wakeup方法的API还告诉我们,如果当前Selector没有阻塞在select方法上,那么本次wakeup调用会在下一次select阻塞的时候生效,这个道理很简单,wakeup方法写入一个字节,下次poll等待的时候立即发现可读并返回,因此不会阻塞。

     具体到源码级别,在linux平台上的wakeup方法其实调用了pipe创建了管道,wakeup调用了EPollArrayWrapperinterrupt方法:

public  void interrupt() 

{
        interrupt(outgoingInterruptFD);
}


    实际调用的是interrupt(fd)的native方法,查看EPollArrayWrapper.c可见清晰的write系统调用:


JNIEXPORT 
void JNICALL
Java_sun_nio_ch_EPollArrayWrapper_interrupt(JNIEnv 
*env, jobject this, jint fd)
{
    
int fakebuf[1];
    fakebuf[
0= 1;
    
if (write(fd, fakebuf, 1< 0) {
        JNU_ThrowIOExceptionWithLastError(env,
"write to interrupt fd failed");
    }
}

    写入一个字节的fakebuf。有朋友问起这个问题,写个注记在此。strace充分利用对了解这些细节很有帮助。

分享到:
评论

相关推荐

    基于jQuery Selector.js插件实现的联动下拉框表单美化效果源码.zip

    本项目利用jQuery的一个插件——Selector.js,实现了联动下拉框的表单美化效果。下面我们将深入探讨这个主题。 首先,jQuery Selector.js插件是jQuery的一个扩展,它提供了更强大的选择器功能,使得开发者能够更加...

    Java-NIO之Selector.doc

    如果Selector正处于阻塞状态,`selector.wakeup()`方法可以用来中断阻塞并让其重新检查通道。这在需要立即处理新注册事件时非常有用。例如,当线程B注册了一个写事件,线程A需要被唤醒以便在下一次`select()`调用中...

    Android文字颜色背景触摸点击反馈色之selector.zip

    "Android文字颜色背景触摸点击反馈色之selector.zip"这个压缩包文件包含了一些关于如何实现Android界面元素(如文字和背景)在触摸点击时改变颜色以提供用户反馈的技术。让我们深入探讨这个话题。 首先,`selector`...

    【IT十八掌徐培成】Java基础第27天-03.NIO-Selector.zip

    4. **选择事件**:接着,通过`selector.select()`或`selector.select(timeout)`方法,Selector会阻塞等待,直到至少有一个已注册的通道有我们关心的事件发生,或者达到指定的超时时间。返回值表示有多少个通道处于...

    selector.js

    selector.js

    Java_NIO-Selector.rar_java nio_selector

    - **创建Selector**:首先,我们需要通过`java.nio.Selector.open()`方法创建一个Selector实例。 - **注册Channel**:然后,我们可以将ServerSocketChannel、SocketChannel或其他类型的通道注册到Selector上,指定...

    GA_feature_selector.zip_GLCM_MATLAB GLCM _feature

    根据压缩包内的文件名称“GA_feature_selector.m”,我们可以推测这可能是一个MATLAB脚本文件,用于实现GLCM特征选择的过程。通常,这样的脚本会读取图像,计算GLCM,然后提取出一系列的纹理特征,并可能包含特征...

    Android-Ultra-Photo-Selector.zip

    这个项目位于"Android-Ultra-Photo-Selector.zip"压缩包内,包含完整的源码以及相关文档,为开发者提供了学习和参考的素材。 项目名称"Android Ultra Photo Selector"表明其主要功能是实现高级的图片选择器,针对...

    multi-image-selector.rar

    "multi-image-selector.rar"是一个针对这一需求的解决方案,它提供了一个可定制的多图片选择器,允许用户根据设定的参数来挑选照片。下面我们将详细探讨这个组件的关键知识点。 1. **多图选择器**:multi-image-...

    jquery.selector-px.js

    jquery.selector-px.js 在微信端实现苹果的下拉框的选取

    前端开源库-matches-selector.zip

    这通常通过下载zip文件并将其解压,然后通过 `&lt;script&gt;` 标签引入`matches-selector.js`文件,或者使用CDN链接。 - 在JavaScript中,你可以调用`matchesSelector(element, selector)`来检查元素是否匹配选择器。...

    SMC 空气组合原件选型软件Air_Combi._Selector.zip

    Selector”这一专业软件工具,旨在简化空气组合原件的选择过程。 SMC的“Air Combi. Selector”选型软件是专为配合其各类空气组合原件而设计的,这些原件包括但不限于过滤器、调节器、润滑器(FRL组件)、气缸、...

    selector.java

    selector.java

    uniapp_date_and_time_selector.zip

    `uniapp_date_and_time_selector.zip`文件很可能是包含了一个uni-app项目,该项目专注于实现一个日期和时间选择器功能。以下是对这个主题的详细讲解: 1. **uni-app框架**:uni-app是一个使用Vue.js开发的所有端的...

    GA_feature_selector.rar_GA_GA matlab_feature matlab_ga+MATLAB_ma

    压缩包中的“GA_feature_selector.m”是主MATLAB脚本,很可能包含了遗传算法特征选择的完整实现。此文件可能包含以下部分: 1. **初始化**:定义种群大小、代数限制、交叉概率、变异概率等遗传算法参数。 2. **编码...

    Java NIO——Selector机制解析三(源码分析)

    3. **获取事件**:调用`Selector.selectedKeys()`会返回一个`Set&lt;SelectionKey&gt;`,包含了所有已经准备就绪的事件。我们可以通过遍历这个集合,获取具体的事件信息,例如哪个Channel可读、可写或连接已完成。 4. **...

    PyPI 官网下载 | selector-0.8.10.tar.gz

    资源来自pypi官网。 资源全名:selector-0.8.10.tar.gz

    Contact Selector.zip

    Contact Selector介绍: 打开设备的联系人列表,选择某个联系人,获取联系人信息,包括头像、姓名等等。   测试环境: Eclipse 4.2, Android 3.0 以上。 注意:测试环境并不代表适用环境。  

    一个可以用代号处理控件的阴影效果,以及用代号在TextView、EditText、Button等控件设置selector.zip

    本资源“一个可以用代号处理控件的阴影效果,以及用代号在TextView、EditText、Button等控件设置selector.zip”主要涵盖了两个方面的内容:一是如何通过代码实现控件的阴影效果,二是如何为常见的UI组件如TextView、...

Global site tag (gtag.js) - Google Analytics