epoll模型

Netty源码—一、server启动(1)

淺唱寂寞╮ 提交于 2020-03-16 05:26:12
说明:netty源码系列是基于4.1.25版本的netty源码的 Netty作为一个Java生态中的网络组件有着举足轻重的位置,各种开源中间件都使用Netty进行网络通信,比如Dubbo、RocketMQ。可以说Netty是对Java NIO的封装,比如ByteBuf、channel等的封装让网络编程更简单。 在介绍Netty服务器启动之前需要简单了解两件事: reactor线程模型 linux中的IO多路复用 reactor线程模型 关于reactor线程模型请参考 这篇文章 ,通过不同的配置Netty可以实现对应的三种reactor线程模型 reactor单线程模型 reactor多线程模型 reactor主从多线程模型 // reactor单线程模型,accept、connect、read、write都在一个线程中执行 EventLoopGroup group = new NioEventLoopGroup(1); bootStrap.group(group); // reactor多线程,accept在bossGroup中的一个线程执行,IO操作在workerGroup中的线程执行 EventLoopGroup bossGroup = new NioEventLoopGroup(1); EventLoopGroup workerGroup = new

Python学习第九天

拟墨画扇 提交于 2020-03-03 08:29:20
生产者-消费者模型: 看下面的例子哦: 1 import threading,queue 2 import time 3 def consumer(n): 4 while True: 5 print("\033[32;1mconsumer [%s]\033[0m get task: %s"%(n,q.get())) 6 time.sleep(1) 7 q.task_done() 8 def producer(n): 9 count=1 10 while True: 11 print('producer [%s] produced a new task: %s'%(n,count)) 12 q.put(count) 13 count += 1 14 q.join()#queue is emtpy 15 print('all tasks has been cosumed by consumers...') 16 q=queue.Queue() 17 c1=threading.Thread(target=consumer,args=[1,]) 18 c2=threading.Thread(target=consumer,args=[2,]) 19 c3=threading.Thread(target=consumer,args=[3,]) 20 21 p=threading.Thread

select,poll,epoll笔记

不想你离开。 提交于 2020-02-17 11:08:22
进程获取磁盘中的数据过程: 1.进程向内核发起一个调用 2.内核收到系统调用,向磁盘发送读取命令 3.磁盘收到内核命令后,将文件载入到内核的内存空间里面 4.内核的内存空间接收到数据后,将数据copy到进程的内存空间(此处发生IO) 5.进程的内存空间得到数据后,给内核发送通知 6.内核把接收到的通知回复给进程,此过程为唤醒进程,然后进程得到数据进行下一步操作 阻塞:进程发起IO调用,进程又不得不等待IO完成,此时CPU把进程切换出去,进入睡眠状态,称为阻塞IO 非阻塞:进程发起IO调用,知道还需一段时间完成,就立即通知进程进行别的操作,则为非阻塞IO 事件(信号)驱动I/o 水平触发的事件驱动机制:内核通知进程来读取数据,进程可以不立即处理,下次调用epoll_wait()会再次通知 边缘触发:内核只通知一次让进程来读取数据,进程可以在超时时间内随时来读取数据 NGINX采用了边缘触发 Reactor模型,处理并发IO比较常见的一种模式,用于同步IO 来源: CSDN 作者: climzhong 链接: https://blog.csdn.net/weixin_43858402/article/details/104353874

高并发多路IO之select,poll和epoll模型区别与代码实现

≡放荡痞女 提交于 2020-01-28 07:53:34
多路IO之select 优点:单进程下支持高并发,可以跨平台 缺点:多次从内核到应用,应用到内核的数组拷贝;    每次内核都会重置填写的数据    最大支持1024客户端,原因在于fd_set定义使用了FD_SETSIZE,大小为1024; 以下是select模型server代码: #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/socket.h> #include <sys/wait.h> #include <netinet/in.h> #include <errno.h> #include <fcntl.h> #include <sys/select.h> #include <ctype.h> int main(){ int lfd = socket(AF_INET,SOCK_STREAM,0); struct sockaddr_in serv; bzero(&serv,sizeof(serv)); serv.sin_port = htons(8888); serv.sin_family = AF_INET; serv.sin_addr.s_addr

c coroutine

半世苍凉 提交于 2020-01-12 23:52:34
今天看了下云风写的关于 c coroutine 博客 ( 代码 ), 发现 coroutine 实现原理其实还比较简单,就用户态栈切换,只需要几十行汇编,特别轻量级。 具体实现 1. 创建一个coroutine: 也就是创建一块连续内存,用于存放栈空间,并设置好入口函数所需要的寄存器   makecontext glibc c语言实现 2. resume coroutine: push保存当前执行上下文的寄存器到栈上,修改%rsp寄存器, jmp 到指定coroutine 执行指令位置,pop 恢复寄存器,开始执行 swapcontext glibc 汇编实现 3. yield coroutine: 同resume 栈切换涉及寄存器操作,得用汇编实现, x86 8个通用寄存器,x64 16个,通过push 保存到栈,pop 恢复到寄存器;比较重要寄存器%rsp 栈顶指针,%rip 指令指针不能直接操作,通过call、jmp 跳转新的Code执行位置。 在64汇编中,并不需要对16个寄存器都备份,其中%rax作为返回值、%r10 %r11 被调用方使用前会自己备份. 参考: X86-64寄存器和栈帧 X86-64寄存器的变化,不仅体现在位数上,更加体现在寄存器数量上。新增加寄存器%r8到%r15。加上x86的原有8个,一共16个寄存器。 刚刚说到,寄存器集成在CPU上

Nginx 事件基本处理流程分析

萝らか妹 提交于 2020-01-09 00:32:40
说明:本文章重点关注事件处理模型。有兴趣的同学可以去 http://tengine.taobao.org/book/ 查找更多资料。Tengine应该是淘宝基于Nginx自己做的修改。这个地址的文档还在不断的完善更新中,内容算是比较全面的。 程序流程图: 说明: 一、进程生成顺序 1.main(src/core/nginx.c)函数启动ngx_master_process_cycle,启动主服务进程。 2.ngx_master_process_cycle(src/os/unix/ngx_process_cycle.c)里面调用ngx_start_worker_processes. 3.ngx_start_worker_processes(src/os/unix/ngx_process_cycle.c)里面循环执行 生成特定数量的进程池。 4.ngx_spawn_process(src/os/unix/ngx_process.c)根据指定的respawn选项fork子进程,相关子进程信息保存在全部ngx_processes数组(ngx_process_t ngx_processes[NGX_MAX_PROCESSES])中,子进程的运行过程通过参数proc指定,这里是ngx_worker_process_cycle(src/os/unix/ngx_process_cycle.c)

[原]HAproxy 代理技术原理探究

╄→尐↘猪︶ㄣ 提交于 2019-12-31 02:04:11
HAproxy 技术分享 简介 HAProxy是一款提供高可用性、负载均衡以及基于TCP(第四层)和HTTP(第七层)应用的代理软件 Features 1.免费 2.能够做到4层以上代理 3.高性能 4.高稳定性 使用案例 淘宝CDN(HTTP反向代理) 测试: HTTP代理 ab -i -c 500 -n 100000 | --- node 8910 URL = / HAproxy| --- node 8911 URL = / | --- node 8912 URL = / | --- node 8913 /test/ (reqisetbe ^[^\ ]*\ /(test|uri)/ server_uri_route) #按照规则转发 ####### haproxy : (单独由haproxy进行均衡负载) Concurrency Level: 500 Time taken for tests: 32.562 seconds Complete requests: 100000 Failed requests: 0 Write errors: 0 Total transferred: 36606588 bytes HTML transferred: 0 bytes Requests per second: 3071.02 [#/sec] (mean) Time per

Netty-6、Netty 线程模型

不羁的心 提交于 2019-12-09 11:03:05
1 Proactor和Reactor Proactor和Reactor是两种经典的多路复用I/O模型,主要用于在高并发、高吞吐量的环境中进行I/O处理。 I/O多路复用机制都依赖于一个事件分发器,事件分离器把接收到的客户事件分发到不同的事件处理器中,如下图: 1.1 select,poll,epoll 在操作系统级别select,poll,epoll是3个常用的I/O多路复用机制,简单了解一下将有助于我们理解Proactor和Reactor。 1.1.1 select select的原理如下: 用户程序发起读操作后,将阻塞查询读数据是否可用,直到内核准备好数据后,用户程序才会真正的读取数据。 poll与select的原理相似,用户程序都要阻塞查询事件是否就绪,但poll没有最大文件描述符的限制。 1.1.2 epoll epoll是select和poll的改进,原理图如下: epoll使用“事件”的方式通知用户程序数据就绪,并且使用内存拷贝的方式使用户程序直接读取内核准备好的数据,不用再读取数据 1.2 Proactor Proactor是一个异步I/O的多路复用模型,原理图如下: 用户发起IO操作到事件分离器 事件分离器通知操作系统进行IO操作 操作系统将数据存放到数据缓存区 操作系统通知分发器IO完成 分离器将事件分发至相应的事件处理器

Netty学习三:线程模型

本秂侑毒 提交于 2019-12-09 11:02:45
1 Proactor和Reactor Proactor和Reactor是两种经典的多路复用I/O模型,主要用于在高并发、高吞吐量的环境中进行I/O处理。 I/O多路复用机制都依赖于一个事件分发器,事件分离器把接收到的客户事件分发到不同的事件处理器中,如下图: 1.1 select,poll,epoll 在操作系统级别select,poll,epoll是3个常用的I/O多路复用机制,简单了解一下将有助于我们理解Proactor和Reactor。 1.1.1 select select的原理如下: 用户程序发起读操作后,将阻塞查询读数据是否可用,直到内核准备好数据后,用户程序才会真正的读取数据。 poll与select的原理相似,用户程序都要阻塞查询事件是否就绪,但poll没有最大文件描述符的限制。 1.1.2 epoll epoll是select和poll的改进,原理图如下: epoll使用“事件”的方式通知用户程序数据就绪,并且使用内存拷贝的方式使用户程序直接读取内核准备好的数据,不用再读取数据 1.2 Proactor Proactor是一个异步I/O的多路复用模型,原理图如下: 用户发起IO操作到事件分离器 事件分离器通知操作系统进行IO操作 操作系统将数据存放到数据缓存区 操作系统通知分发器IO完成 分离器将事件分发至相应的事件处理器

带你手把手重读 Handler 源码,聊聊那些你所不知道一二三

谁都会走 提交于 2019-12-04 21:04:54
大家应该都知道,Android 的消息机制是基于 Handler 实现的。还记得一年前的自己就看了几篇博客,知道了 Handler、Looper、MessageQueue 就自以为了解了 Handler 的原理。但其实看源码的过程中慢慢就会发现,Handler 的内容可不止这点, 像同步屏障、 Handler 的 native 层的阻塞唤醒机制等等这些知识以前就没有理解清楚。因此写下这篇文章,从头开始重塑对 Handler 的印象。 觉得文章太长的可以找我拿了完整的PDF自行研究 参考: (更多完整项目下载。未完待续。源码。图文知识后续上传github。) 可以点击 关于我 联系我获取完整PDF ( VX:mm14525201314 ) Handler 采用的是一种生产者-消费者模型,Handler 就是生产者,通过它可以生产需要执行的任务。而 Looper 则是消费者,不断从 MessageQueue 中取出 Message 对这些消息进行消费,下面我们看一下其具体的实现。 发送消息 post & sendMessage 首先我们都知道,Handler 对外主要有两种方式来实现在其所在 Looper 所在线程执行指定 Runnable ——post 及 sendMessage ,它们都有对应的 delay 方法 。而不论是 post 还是 sendMessage ,都会调用到