异步io

小白对异步IO的理解

大兔子大兔子 提交于 2019-11-28 08:59:52
前言 看到越来越多的大佬都在使用python的异步IO,协程等概念来实现高效的IO处理过程,可是我对这些概念还不太懂,就学习了一下。 因为是初学者,在理解上有很多不到位的地方,如果有错误,还希望能够有人积极帮我指出。 下面就使用一个简单的爬虫的例子,通过一步一步的改进,最后来用异步IO的方式实现。 1. 阻塞的IO 我们要实现一个爬虫,去爬百度首页n次,最简单的想法就是依次下载,从建立socket连接到发送网络请求再到读取响应数据,顺序进行。 代码如下: 1 import time 2 import socket 3 import sys 4 5 def doRequest(): 6 sock = socket.socket() 7 sock.connect(('www.baidu.com',80)) 8 sock.send("GET / HTTP/1.1\r\nHost: www.baidu.com\r\nConnection: Close\r\n\r\n".encode("utf-8")) 9 response = sock.recv(1024) 10 return response 11 12 def main(): 13 start = time.time() 14 for i in range(int(sys.argv[1])): 15 doRequest() 16

Http-Netty-Rpc-Service系统

ぐ巨炮叔叔 提交于 2019-11-28 08:27:28
20190823rpc系统修改日志 https://github.com/KouReal/Rpc-Netty-Registry/tree/master 将httpserver模块的httptask去掉,直接在httpserverhandler调用rpcproxy的call的rpcclient的invokewithfuture的ctx的writeandflush,,这一系列调用过程都是不会阻塞的,除了第一次调用某个服务创建rpcclient是有阻塞cpu的,之后就全在线程内执行,不参与io网络传输。 为什么要去掉httptask,因为httptask是线程,意味着每次从httpserver接受到一个请求,都会创建一个httptask线程,而这个httptask线程会根据future使自己waitting,parknonos,而线程数量不能创建的太多,尤其不能和请求数量正比例增长,因为线程的来回切换会得不偿失,但是如果用线程池来对付请求,也不行,因为线程池数量有限,并且在线程池的线程里等待网络io必然会耗费时间,这和传统bio问题是一样的,这个线程池也就无法满足高并发请求,总之,高并发不意味着线程必须多,反而是需要线程的充分利用,追求并行而不是并发,所以是和实际物理cpu并行能力来决定的,在双核cpu,一般双核可以支持并行4线程,所以netty的workergroup默认线程数是4

记一次java的几种IO模型的了解

拈花ヽ惹草 提交于 2019-11-28 07:39:45
IO 1、阻塞型 读写的时候会阻塞,发出请求读写之后线程就会去问东西是否准备好,准备好了就开始读写,这期间的等待就是读写的阻塞。 2、非阻塞型 读写时不会阻塞,工作形式是循环查看是否资源准备好,不管有没有准备好都会告诉你,一直询问,直到准备好 3、多路复用型 有一个线程专门负责循环查询N个资源情况,哪个个socket的好了就通知哪个,这种有点像一个包工头和一群工人,一群工人都去包工头 那里干活,什么时候干活去哪里干活要等包工头通知 4、信号型 在请求读写操作的时候会注册一个信号,就可以去干其他的事情了,有点像去买东西人去了货可能断了还没到,你留着个电话,货到了给 你打电话,就可以来取了。 5、异步型 异步型发起异步读写请求之后就立马可以做其他事情去了,当系统知道你发起的是一个异步的读写请求时,也是会立即告诉你申请成功了 ,当系统再次通知你的时候,活已经干完了 ,这也是和信号型的区别 来源: https://blog.csdn.net/qq_35562567/article/details/100036326

高级IO

有些话、适合烂在心里 提交于 2019-11-28 06:24:22
高级IO: 五种IO模型:阻塞IO; 非阻塞IO; 信号驱动IO;异步IO;多路转接IO IO操作分为两个过程:等待/数据拷贝 阻塞IO: 发起IO调用后,若不具备IO条件,则等待IO条件具备,拷贝数据后返回 非阻塞IO: 发起IO调用后,若不具备IO条件,则立即报错返回,若具备IO条件则立即拷贝数据后返回 信号驱动IO: 先定义IO信号处理,若IO条件具备则直接信号通知进程,发起调用,拷贝数据后返回 异步IO: 先定义IO信号处理,发起异步IO调用,直接返回。让别人进行IO等待,等待IO条件具备后拷贝数据 (与信号驱动的区别是拷贝数据是由别人来完成的)信号通知进程IO完成 ** 阻塞:为了完成功能发起调用,如果当前不具备完成条件,则一直等待,直到完成后返回。 非阻塞:为了完成功能发起调用,如果当前不具备完成条件,直接报错返回;通常需要循环处理 阻塞与非阻塞:调用功能当前不具备完成条件是否立即返回。 同步:为了完成功能发起调用,如果当前不具备完成条件,则自己等待完成功能后返回 异步:为了完成功能发起调用,但是功能由别人来完成 同步与异步的区别:功能是否由自己来完成 同步操作通常都是阻塞操作 异步包含两种: 异步阻塞操作:等待别人完成操作 异步非阻塞操作:不等待别人完成操作 同步与异步的优缺点: 同步:流程控制简单,但是效率相对较低 异步:流程控制较难,但是效率相对较高 多路转接IO

线程,进程,协程面试知识点

微笑、不失礼 提交于 2019-11-28 04:12:50
2. threading.local的作用? import threading # 创建全局ThreadLocal对象: localVal = threading.local() localVal.val = "Main-Thread" def process_student(): print( '%s (in %s)' % (localVal.val, threading.current_thread().name)) def process_thread(name): #赋值 localVal.val = name process_student() t1 = threading.Thread(target= process_thread, args=('One',), name='Thread-A') t2 = threading.Thread(target= process_thread, args=('Two',), name='Thread-B') t1.start() t2.start() t1.join() t2.join() print(localVal.val) #打印结果: ''' One (in Thread-A) Two (in Thread-B) Main-Thread ''' ''' threading。local()这个方法:用来保存一个全局变量

IO并发

我们两清 提交于 2019-11-28 01:25:32
IO分类 IO分类:阻塞IO,非阻塞IO,IO多路复用,异步IO等 阻塞IO 定义:在执行IO操作时如果执行条件不满足则阻塞。阻塞IO是IO的默认形态。 效率:阻塞IO是效率很低的一种IO。但是由于逻辑简单所以是默认IO行为。 阻塞情况: 因为某种执行条件没有满足造成的函数阻塞         如:accept input recv等 处理IO的时间较长产生的阻塞状态         如:网络传输,大文件读写等 非阻塞IO 定义:通过修改IO属性行为,使原本阻塞的IO变为非阻塞的状态 设置套接字为非阻塞IO sockfd.setblocking(bool) 功能:设置套接字为非阻塞IO 参数:默认为True,表示套接字IO阻塞;设置为False则套接字IO变为非阻塞 超时检测:设置一个最长阻塞时间,超过该时间后则不再阻塞等待。 sockfd.settimeout(sec) 功能:设置套接字的超时时间 参数:设置的时间 代码示例: 1 from socket import * 2 from time import * 3 4 # 日志文件 5 f = open('log.txt','a+') 6 7 # tcp 服务端 8 sockfd = socket() 9 sockfd.bind(('0.0.0.0',8888)) 10 sockfd.listen(5) 11 12 #

Java IO流,详细介绍,及用法

不问归期 提交于 2019-11-27 21:58:48
三种IO共存:BIO、NIO、AIO Java BIO BIO 全称Block-IO 是一种同步且阻塞的通信模式。是一个比较传统的通信方式,模式简单,使用方便。但并发处理能力低,通信耗时,依赖网速。 Java NIO NIO 全称Non-Block IO 是Java SE 1.4版以后,针对网络传输效能优化的新功能。是一种非阻塞同步的通信模式。 NIO 与原来的I/O有同样的作用和目的,他们之间最重要的区别是数据打包和传输方式。原来的I/O 以流的方式处理数据,而NIO 以块的方式处理数据。 面向流的I/O系统一次一个字节的处理数据。一个输入流产生一个字节的数据,一个输出流的消费一个字节的数据。 面向快的I/O系统以快的形式处理数据。每一个操作都在一步中产生或者消费一个数据块。按快处理数据比较流式的的字节处理数据速度要快得多。但是面向块的I/O 缺少一些面向流的I/O所具有的优雅性和简单性。 Java AIO AIO 全称Asynchronous IO 是异步非阻塞的IO。是一种非阻塞异步的通信模式。 在NIO的基础上引入了新的异步通道的概念,并提供了异步文件通道和异步套接字通道的实现。 三种IO的区别: BIO:同步阻塞I/O模式。 NIO:同步非阻塞模式。 AIO:异步非阻塞I/O模式。 同步阻塞模式:在这种模式下,我们的工作模式是先来到厨房,开始烧水

【IO多路复用】

核能气质少年 提交于 2019-11-27 21:11:43
原文: http://blog.gqylpy.com/gqy/234 " 目录 一、IO模型介绍 二、阻塞IO(blocking IO) 三、非阻塞IO(non-blocking IO) 四、多路复用IO(IO multiplexing) 五、异步IO(Asynchronous I/O) 六、模型比较分析 七、关于select、poll、epoll 一、IO模型介绍 为了更好地了解IO模型,我们需要事先回顾下: 同步、异步、阻塞、非阻塞 同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非阻塞(non-blocking)IO分别是什么,到底有什么区别?这个问题其实不同的人给出的答案都可能不同,比如wiki,就认为asynchronous IO和non-blocking IO是一个东西。这其实是因为不同的人的知识背景不同,并且在讨论这个问题的时候上下文(context)也不相同。所以,为了更好的回答这个问题,我先限定一下本文的上下文。 本文讨论的背景是Linux环境下的network IO。本文最重要的参考文献是Richard Stevens的“UNIX® Network Programming Volume 1, Third Edition: The Sockets Networking ”,6.2节“I/O Models

【TCP】tcp协议通信中io

烂漫一生 提交于 2019-11-27 20:41:19
阻塞IO recv,接收数据,若没有,将阻塞, 当对方发数据来后,linux内核缓冲区得到数据, 内核数据复制到recv()调用所在的用户空间, 阻塞解除,进行下一步处理, 非阻塞IO 轮询调用recv函数接收数据, 没有数据,立即返回,然后继续调用, 根据返回值来判定时候读到数据, 这种方式大量消耗CPU,应用范围小,一般和selectIO复用配合使用, IO复用 select机制,可以轮询多个fd的状态变化, 进而决定recv是否要进行数据的读,而不致像上面两种极端, 但是所轮询的多个fd都没有状态变化,也将阻塞, 同时select也可以设置等待时间,避免干等, 信号驱动IO 建立一个信号,当有数据到来的时候,通知上层应用去读取数据, 这种模型用的较少,信号发送有延迟,处理数据有延迟,内核数据也可能发生变化,   为什么说信号驱动的延迟大呢?   因为有数据了,得发送一个信号去通知上层应用,   通知之后,不一定马上来读取,   有机会读取了,还得跑过来读 异步IO 异步IO,上层应用提供了一个应用层的缓冲区, 有数据了,内核会主动,,的把数据塞到应用层提供的这个缓冲区,而不用像上面那样有那么的工序去主动地读,不过这个复杂工序你暂时没办法了解很深入,但是可以肯定的是,主动读肯定涉及到很多过程处理, 来源: https://www.cnblogs.com/itplay/p

并发模型与IO模型梳理

坚强是说给别人听的谎言 提交于 2019-11-27 19:02:16
并发模型 常见的并发模型一般包括3类,基于线程与锁的内存共享模型,actor模型和CSP模型,其中尤以线程与锁的共享内存模型最为常见。由于go语言的兴起,CSP模型也越来越受关注。基于锁的共享内存模型与后两者的主要区别在于,到底是通过共享内存来通信,还是通过通信来实现访问共享内存。由于actor模型和CSP模型,本人并不是特别了解,我主要说说最基本的并发模型,基于线程与锁的内存共享模型。 为什么要并发,本质都是为了充分利用多核CPU资源,提高性能。但并发又不能乱,为了保证正确性,需要通过共享内存来协调并发,确保程序正确运转。无论是多进程并发,还是多线程并发,要么通过线程间互斥同步(spinlock,rwlock,mutex,condition,信号量),要么通过进程间通信(共享内存,管道,信号量,套接字),本质都是为了协同。多线程和多进程本质类似,尤其是linux环境下的pthread库,本质是用轻量级进程实现线程。下面以网络服务为例,简单讨论下多线程模型的演进。 最简单的模型是单进程单线程模型,来一个请求处理一个请求,这样效率很低,也无法充分利用系统资源。那么可以简单的引入多线程,其中抽出一个线程监听,每来一个请求就创建一个工作线程服务,多个请求多个线程,这就是多线程并发模型。这种模式下,资源利用率是上去了,但是却有很多浪费,线程数与请求数成正比,意味着频繁的创建/销毁线程开销