为什么 asyncio 单线程 速度还能那么快
早一点是VHDL,现在是Verilog,c语言,matlab,verilog,vhdl用的多。
偶尔需要c++或者labview做上位机和硬件通信。
编程语言俗称“计算机语言”,种类非常的多,总的来说可以分成机器语言、汇编语言、高级语言三大类。电脑每做的一次动作,一个步骤,都是按照已经用计算机语言编好的程序来执行的,程序是计算机要执行的指令的集合,而程序全部都是用我们所掌握的语言来编写的。所以人们要控制计算机一定要通过计算机语言向计算机发出命令。
目前通用的编程语言有两种形式:汇编语言和高级语言。
能用汇编写最好,不过汇编要求太高了
一般就要求C就好了,硬件很少用Java做的
莫凡python asyncio教程那边过来的吧?
我这两天也在学习asyncio,之前都是用threading写爬虫,刚拿我之前的一个贴吧爬虫的需求尝试了一下,确实是快,爬某吧会员列表,协程的速度比我线程的速度要快好几倍:
协程与多线程速度对比1
(测试1,爬1000张页面。aio.py脚本是协程;asy2.py脚本是多线程,线程数是15)
协程与多线程速度对比2
(测试2,爬10000张页面。aio.py脚本是协程;asy2.py脚本是多线程,线程数是100)
至于为什么快,我的理解是,协程更适合高IO操作,低计算密集的程序,而爬虫本质上其实都是IO操作(请求网络内容并下载是网络IO,下载下来并写入硬盘也是本地IO)。
而多线程之所以在这方面没有协程快,主要是因为:
线程开销更大(主要在于占用cpu资源,以及多线程之间上下文切换的开销,参考:多线程的线程开销)
而实际上爬虫在干什么呢?不停下载数据而已,基本都不需要cpu计算,所以要cpu的开销做什么呢?
最后再来看一下跑2个脚本时我的电脑资源占用对比:
跑协程时
跑多线程(线程数100)时
所以为什么协程快?这就一目了然了。
(P.S. 用asyncio需要确保写对了才行,不然可能会反而比多线程慢,要注意。这方面我也还在学习中。)
这个也要看他的主频是多高了.比如单核CPU3.06就比双核2.6的主频要高,但是单线程是运行一个程序或少个程序能显示出来他的速度,运行东西多了的话就会被多线程给比下去了.
介绍.
MMO游戏毫无疑问是当前主流趋势,不管从技术角度还是从流行趋势.曾几何时,写一个MMO游戏是需要大量的预算和非常复杂的底层的编程技术.最近,事情发生变化了.很多基于动态语言的现在框架可以做到处理数以千计的玩家连接.(数以千计,咋一听起来有点挫啊,可是仔细想想一个单独的进程也差不多就是这个级别,大型的MMO都是在这个基础上做多进程扩展).同时html 5和WebSockets标准能够实现网页运行的实时画面游戏.
python可能不是创建可扩展的非阻塞服务器的最流行的工具,尤其和node.js对比.但是最新版本的python瞄准了这一问题.asyncio和async/await能够是异步的语言看起来和常规的代码一样直接.所以我们来通过这些新特性来演示一下如何创建一个MMO游戏.
变成异步
一个gameserver能够处理大量玩家的并行连接,同时要做到实时.一个方法是创建线程,可是这种方法并不适用.运行几千个线程,cpu就要不停的切换线程(context switching),这样就非常抵消.如果用多进程呢?那更糟糕,因为需要占用更多的内存.使用pyuthon还有一个更大的问题 - 通常python解释器(CPython)设计上不能做到真正的多线程,它的目标是单线程的效率. 这就是它使用GIL(global interpreter lock)的原因,这就使得python不同同时运行代码,来防止共享对象的使用. 一般情况下,解释器切换到另一个线程发生在当前线程正咋等待io或者其他.这确实能够做到费阻塞的io.因为只阻塞在一个线程里.然而,这并不能利用多线程的优势,因为不能够同时运行代码,即使是在多核cpu上面.其实呢, 在单线程里面也是完全可以做到非组赛io的,这样就避免了大量的context-switching.
这种单线程非阻塞的实现通过纯python就可以做到.你需要的是select.你自己要写一个事件循环.这种方法需要你把逻辑都写在一个地方, 然而你的应用会很快变成非常复杂的状态机.有很多框架来简化这个方法,最流行的是tornado和twisted.他们都是通过回调实现了非常复杂的协议.(有点像node.js)这些框架运行自己的事件循环,在特定事件发生时调用你定义的回调.虽然这样已经非常好了,但是这个风格是callback,代码会变得脆弱(不至于吧).和这个相对应的是同步代码.为什么不在一个线程里做到这些呢?
那么我就就要讨论一个新概念, microthreads,(是叫微线程么).意思就是在单线程里面同步运行很多任务.当你调用一个阻塞的任务,背后的"manager"会运行一个事件循环.当一个事件发生,这个manager就会通知等待这个事件的任务.这个任务就继续运行直到遇到一个阻塞,然后有把运行任务交给manager.
作者:default
链接:https://www.jianshu.com/p/8a51f641da07
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
我们首先要明白,上边的种种分析,都是为了营造一个Redis很快的氛围!官方FAQ表示,因为Redis是基于内存的操作,CPU不是Redis的瓶颈,Redis的瓶颈最有可能是机器内存的大小或者网络带宽。既然单线程容易实现,而且CPU不会成为瓶颈,那就顺理成章地采用单线程的方案了(毕竟采用多线程会有很多麻烦!)。
首先需要明确一点,asyncio使用单线程、单个进程的方式切换(通常程序等待读或写数据时就是切换上下文的时机),那这样效率高嘛?实践是检验真理的唯一标准。我们用之前介绍的concurrent.futures和asyncio分别试验下。当然下面例子的结果仅供参考,因为无法保证被请求的网站的服务水平,这会造成对结果或多或少有影响,可以多跑几次综合的来看。仅供参考!
吴善益母: redis用自己实现的事件分离器,代码量很短,没有cas,没有lock.那么memcache为什么要多线程呢,因为他是一种通用的kv数据库.不会因为某个线程慢而导致其他的线程问题,且能够完全的使用多核的cpu.这些是redis不足的地方.两者都使用epoll,no-blocking io.
海淀区17791869876: 多线程,单线程速度差很多,要如何提高多线程 - ?
吴善益母: 我认为,多线程提高效率是有前提的. 如果只是让CPU执行计算,就像你说得,现在的微机都是分时处理,单线程和多线程的效率几乎一致,甚至单线程还要快一点,关于这个我是做过测试的.多线程提高效率的情况是,比如需要等待IO或者用户响应的情况. 举个列子,一个ping的小程序.从网址192.168.1.1到192.168.1.255,循环ping,假设每个网址都ping不通,计算机等待3秒超时. 如果使用单线程,则需要255*3秒时间.如果使用C#线程池或者4.0的并行计算,则会节约10倍左右的时间.
海淀区17791869876: redis是个单线程的程序,为什么会这么快呢?每秒10000?这个有点不解,具体是快在哪里呢?EPOLL?内存? - ?
吴善益母: 个人觉得,1、Redis本身是内存数据库,内存读取速度优势是绝对的;2、Redis存储结构上讲,key-value存储.3、Redis本身结构设计上.(这个可以研究一下源码)
海淀区17791869876: Redis 为什么使用单进程单线程方式也这么快 - ?
吴善益母: Redis采用的是基于内存的采用的是单进程单线程模型的KV数据库,由C语言编写.官方提供的数据是可以达到100000+的qps.这个数据不比采用单进程多线程的同样基于内存的KV数据库Memcached差. Redis快的主要原因是: 完全基于内存...
海淀区17791869876: 单线程是否比多线程运行速度快,原因是什么??回答满意,再加30分?
吴善益母: 1、这不是绝对的 2、在以前的计算机都只有一个CPU,即使是多线程,也是依靠时间片完成的 3、现在的多核计算机,多线程速度是要快于单线程 回答:宜人家园
海淀区17791869876: 我用java写了个多线程排序,发现用单线程和多线程的速度一样,这是为 - ?
吴善益母: 单线程比多线程更快.你的测试代码只是用了CPU资源.因为多线程需要处理线程的开销,开销多了自然没有单线程快. 多线程是为了更充分的利用计算机的资源.比如网络,IO,CPU...如果你在for循环里加入一个磁盘写入操作,多线程就会比单线程快了
海淀区17791869876: Redis为什么使用单进程单线程方式 - ?
吴善益母: Redis快的主要原因是: 完全基于内存 数据结构简单,对数据操作也简单 使用多路 I/O 复用模型
海淀区17791869876: redis单线程怎么理解 - ?
吴善益母: 但线程,只能靠单个处理器速度,内存速度,处理器上的缓存速度,总线传输速度.余下的是你的网络IO.但线程高并发完全依赖程序的运行速度.redis这种东西肯定不是但线程的.一个连接就是一个线程,你这样理解应该不准确.
海淀区17791869876: redis为什么单线程 - ?
吴善益母: 单纯的网络IO来说,量大到一定程度之后,多线程的确有优势, 但并不是单纯的多线程,而是每个线程自己有自己的epoll这样的模型,也就是多线程和multiplexing混合.但是.还要考虑Redis操作的是内存中的数据结构.如果在多线程中操作,...
海淀区17791869876: 网络测试中单线程测试和多线程测速有什么区别? - ?
吴善益母: 什么是进程? 当一个程序开始运行时,它就是一个进程,进程包括运行中的程序和程序所使用到的内存和系统资源. 而一个进程又是由多个线程所组成的.什么是线程? 线程是程序中的一个执行流,每个线程都有自己的专有寄存器(栈指针、...