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

消息写

 
阅读更多
   处理流程
   正如JDK规范中指出一个Channel任意时刻只能执行单个线程的写操作。单个Nioworker可以顺序处理多个socketChannel的写操作,单个SocketChannel上的多次写操作会事先放入到写请求队列;结果由Nioworker调度执行。当Channel被调度时正常情况下消息队列会被出列处理之至为空;如果中途Channel内核缓冲区已满,未写入数据将保留在内存中则下次Channel被调度时优先处理上次剩余数据之后出列可能的消息。
   而且一旦内核缓存区满并尝试n次写之后失败,将挂起写操作之后该channel的写入全部保存在消息队里中,等待下一次调度。其实挂起写操作时,selectKey可能修改为支持OP_WRITE,下次select()被唤醒时解挂。在此之前客户端发起的写全部被保存到消息队列中;以下是单个channel的写操作流程。

  写消息逻辑大部分在如下方法中 
  //AbstractNioWorker
   protected void write0(AbstractNioChannel<?> channel) 
  

   写操作数据结构
  之前所有的消息事件中包含消息数据,而这种数据类型由SocketSendBufferPool强制规定;由此可见消息数据必须是ChannelBuffer或FileRegion类型。acquire()方法将所需类型经过处理转变为SendBuffer。它的实现包括
     处理FileRegion的FileSendBuffer
    处理ChannelBuffer的UnpooledSendBuffer,GatheringSendBuffer
    处理ChannelBuffer的PooledSendBuffer
第1,2种类型比较简单,只是一个简单的代理;重点是第3种类型。单个nioworker中多个Channel会可能会使用多块DirectBuffer;关于DirectBuffer在读消息中详细说明过。
如果写入信息块ChannelBuffer小于等于1024,将返回PooledSendBuffer。当每个Channel消息队列正常处理完,则会立即释放引用计数器。不然PooledSendBuffer会占用,一般来讲接下来的轮询会处理完,直到同段的最后一个处理完,才标志该内存段的为PooledHeader ,假如有一个Channel总是无法写入则占用的内存段不会被释放,这也是“内存泄露”。
  SendBuffer acquire(Object message) {
        if (message instanceof ChannelBuffer) {
            return acquire((ChannelBuffer) message);
        }
        if (message instanceof FileRegion) {
            return acquire((FileRegion) message);
        }

        throw new IllegalArgumentException(
                "unsupported message type: " + message.getClass());
    }
  //SendBuffer
   interface SendBuffer {
        boolean finished();
        long writtenBytes();
        long totalBytes();

        long transferTo(WritableByteChannel ch) throws IOException;
        long transferTo(DatagramChannel ch, SocketAddress raddr) throws IOException;

        void release();
    }
   //PooledSendBuffer
     final class PooledSendBuffer extends UnpooledSendBuffer {

        private final Preallocation parent;

        PooledSendBuffer(Preallocation parent, ByteBuffer buffer) {
            super(buffer);
            this.parent = parent;
        }

        @Override
        public void release() {
            final Preallocation parent = this.parent;
            if (-- parent.refCnt == 0) {
                parent.buffer.clear();
                if (parent != current) {
                    poolHead = new PreallocationRef(parent, poolHead);
                }
            }
        }
    }

  PooledHead始终指向可用的链表头,详细的操作流程及描述如下图

0
0
分享到:
评论

相关推荐

    JavaScript写信息自动匹配类似的消息

    JavaScript写信息自动匹配类似的消息写信息自动匹配类似的消息写信息自动匹配类似的消息写信息自动匹配类似的消息写信息自动匹配类似的消息写信息自动匹配类似的消息写信息自动匹配类似的消息写信息自动匹配类似的...

    LINUX的消息函数的分析

    Linux采用消息队列的方式来实现消息传递。System V的消息队列(message queues)是进程之间互相发送消息的一种异步(asynchronously)方式,在这种情形...当一个新的消息写到队列的时候,这个进程会被唤醒,继续运行。

    消息队列模型C++源码和UML类图

    消息队列在软件开发中是一种重要的并发控制和通信机制,特别是在多线程和分布式系统中。C++作为一种强大的编程语言,提供了丰富的工具和库来实现这种机制。本主题主要探讨的是一个C++实现的消息队列处理机制,包括...

    写了一个很简单的消息队列

    标题中的“写了一个很简单的消息队列”表明这个项目是一个基本的消息队列实现,通常用于在分布式系统中处理异步任务或数据传输。消息队列是计算机科学中的一个重要概念,它允许应用程序通过发送消息来解耦生产者...

    基于Java与Python的多语言支持,实现datax hive动态分区和kafka读写功能的数据集成设计源码

    该项目是一款数据集成解决方案源码,采用Java与Python实现,支持多语言开发环境。...项目核心功能包括动态分区支持、Hive数据集成、Kafka消息读写,并能实现单次读取多写出,适用于大数据处理场景。

    易语言截获写注册表消息源码

    "截获写注册表消息"是操作系统编程中的一个重要概念,注册表是Windows操作系统用来存储配置信息的地方,包括系统设置、应用程序数据等。写入注册表通常是程序设置保存或修改系统设置时的操作。然而,由于注册表的...

    MQ消息测试工具 可直接向MQ写消息

    标题提到的“MQ消息测试工具 可直接向MQ写消息”正是一款这样的实用工具,专门设计用来测试MQ消息接收程序的效能和正确性。 首先,我们要理解MQ消息测试工具的核心功能。这类工具通常具备以下特性: 1. **消息生成...

    基于自写消息平台垃圾短信监管项目的质量管理案例.pptx

    这是一个对自写消息平台垃圾监管项目中质量管理进行分析的软件项目管理案例,可用于软件项目管理课上展示。

    vc++2005写消息日志、读写ini文件

    首先,让我们来看看写消息日志。在C++编程中,日志通常用于记录程序运行时的信息,如错误、警告或调试信息。VC++2005中没有内置的日志系统,但我们可以自定义一个简单的日志模块。这通常涉及创建一个类,该类能够...

    rocketmq用户指南

    - HA(高可用):支持同步双写和异步复制,确保消息的高可用。 #### 12. 消息过滤 - 简单消息过滤:通过简单的逻辑判断,过滤掉不需要的消息。 - 高级消息过滤:允许更复杂的规则来决定哪些消息应该被消费者接收。 ...

    漂亮的消息提示框 消息提示组件 Javascript写的

    函数改变了1.0版需要对确定和取消按钮分别写回调函数及不支持关闭事件的缺陷, 11、完全的封装,对外只暴露一个ymPrompt变量,有效防止与使用者程序变量的冲突。 12、程序(js)与样式(css)的完全分离,取消了1.0中...

    Go-Go写的消息中心服务

    标题中的"Go-Go写的消息中心服务"意味着我们将关注的是利用Go语言的特性和库来创建一个消息中间件。Go语言的并发模型基于CSP(Communicating Sequential Processes)理论,通过goroutines和channels提供了一种结构化...

    易语言源码易语言截获写注册表消息源码.rar

    易语言源码易语言截获写注册表消息源码.rar 易语言源码易语言截获写注册表消息源码.rar 易语言源码易语言截获写注册表消息源码.rar 易语言源码易语言截获写注册表消息源码.rar 易语言源码易语言截获写注册表消息...

    c#写的UDP接收和发送消息

    本项目"**c#写的UDP接收和发送消息**"提供了一个使用C#语言实现的UDP通信的示例代码,帮助开发者理解如何在C#环境下处理UDP数据包的收发。 首先,我们来看UDP的基本概念。UDP协议不建立连接,而是直接将数据报文...

    mq demo 消息 自写demo

    本“mq demo 消息 自写demo”提供的是一款自编写的MQ示例,包含了两种不同的消息模式。解压这个压缩包后,你首先应该阅读"read me"文件,这通常会包含详细的使用指南和注意事项,对于理解和运行demo至关重要。 1. *...

    Python-一个由python写简单和容易使用的消息队列

    Python 消息队列是一种用于进程间通信(IPC)的技术,它允许程序将任务或数据放入队列,然后由其他程序或线程处理,而无需直接交互。这种异步处理方式提高了系统的可扩展性和响应速度,尤其适用于处理大量并发请求的...

    C#写的QQ自动发消息.rar

    ////发送消息,因为QQ屏蔽了 WM_SETTEXT, WM_PASTE 命令,所有采用 EM_REPLACESEL 来实现 NativeMethods.SendMessage(hwndRichEdit, NativeMethods.EM_REPLACESEL, IntPtr.Zero, msg); ////给发送按钮发 鼠标...

    QT 自己写一个消息弹窗源码

    这个资源,是配合此前自己写过的一篇博客“QT 写一个属于自己的消息弹窗MessageBox”所建立的,里面是一个自己写的消息弹窗源码和资源文件,博客里会从头介绍如何自己写一个消息弹窗,有兴趣去朋友可以关注一下!...

    如何写好电视消息最终.ppt

    如何写好电视消息最终.ppt

Global site tag (gtag.js) - Google Analytics