python协程并发量多少(python协程gevent)

导读:今天首席CTO笔记来给各位分享关于python协程并发量多少的相关内容,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!

Python异步编程全攻略

如果你厌倦了多线程,不妨试试python的异步编程,再引入async, await关键字之后语法变得更加简洁和直观,又经过几年的生态发展,现在是一个很不错的并发模型。

下面介绍一下python异步编程的方方面面。

因为GIL的存在,所以Python的多线程在CPU密集的任务下显得无力,但是对于IO密集的任务,多线程还是足以发挥多线程的优势的,而异步也是为了应对IO密集的任务,所以两者是一个可以相互替代的方案,因为设计的不同,理论上异步要比多线程快,因为异步的花销更少, 因为不需要额外系统申请额外的内存,而线程的创建跟系统有关,需要分配一定量的内存,一般是几兆,比如linux默认是8MB。

虽然异步很好,比如可以使用更少的内存,比如更好地控制并发(也许你并不这么认为:))。但是由于async/await 语法的存在导致与之前的语法有些割裂,所以需要适配,需要付出额外的努力,再者就是生态远远没有同步编程强大,比如很多库还不支持异步,所以你需要一些额外的适配。

为了不给其他网站带来困扰,这里首先在自己电脑启动web服务用于测试,代码很简单。

本文所有依赖如下:

所有依赖可通过代码仓库的requirements.txt一次性安装。

首先看一个错误的例子

输出如下:

发现花费了3秒,不符合预期呀。。。。这是因为虽然用了协程,但是每个协程是串行的运行,也就是说后一个等前一个完成之后才开始,那么这样的异步代码并没有并发,所以我们需要让这些协程并行起来

为了让代码变动的不是太多,所以这里用了一个笨办法来等待所有任务完成, 之所以在main函数中等待是为了不让ClientSession关闭, 如果你移除了main函数中的等待代码会发现报告异常 RuntimeError: Session is closed ,而代码里的解决方案非常的不优雅,需要手动的等待,为了解决这个问题,我们再次改进代码。

这里解决的方式是通过 asyncio.wait 方法等待一个协程列表,默认是等待所有协程结束后返回,会返回一个完成(done)列表,以及一个待办(pending)列表。

如果我们不想要协程对象而是结果,那么我们可以使用 asyncio.gather

结果输出如下:

通过 asyncio.ensure_future 我们就能创建一个协程,跟调用一个函数差别不大,为了等待所有任务完成之后退出,我们需要使用 asyncio.wait 等方法来等待,如果只想要协程输出的结果,我们可以使用 asyncio.gather 来获取结果。

虽然前面能够随心所欲的创建协程,但是就像多线程一样,我们也需要处理协程之间的同步问题,为了保持语法及使用情况的一致,多线程中用到的同步功能,asyncio中基本也能找到, 并且用法基本一致,不一致的地方主要是需要用异步的关键字,比如 async with/ await 等

通过锁让并发慢下来,让协程一个一个的运行。

输出如下:

通过观察很容易发现,并发的速度因为锁而慢下来了,因为每次只有一个协程能获得锁,所以并发变成了串行。

通过事件来通知特定的协程开始工作,假设有一个任务是根据http响应结果选择是否激活。

输出如下:

可以看到事件(Event)等待者都是在得到响应内容之后输出,并且事件(Event)可以是多个协程同时等待。

上面的事件虽然很棒,能够在不同的协程之间同步状态,并且也能够一次性同步所有的等待协程,但是还不够精细化,比如想通知指定数量的等待协程,这个时候Event就无能为力了,所以同步原语中出现了Condition。

输出如下:

可以看到,前面两个等待的协程是在同一时刻完成,而不是全部等待完成。

通过创建协程的数量来控制并发并不是非常优雅的方式,所以可以通过信号量的方式来控制并发。

输出如下:

可以发现,虽然同时创建了三个协程,但是同一时刻只有两个协程工作,而另外一个协程需要等待一个协程让出信号量才能运行。

无论是协程还是线程,任务之间的状态同步还是很重要的,所以有了应对各种同步机制的同步原语,因为要保证一个资源同一个时刻只能一个任务访问,所以引入了锁,又因为需要一个任务等待另一个任务,或者多个任务等待某个任务,因此引入了事件(Event),但是为了更精细的控制通知的程度,所以又引入了条件(Condition), 通过条件可以控制一次通知多少的任务。

有时候的并发需求是通过一个变量控制并发任务的并发数而不是通过创建协程的数量来控制并发,所以引入了信号量(Semaphore),这样就可以在创建的协程数远远大于并发数的情况下让协程在指定的并发量情况下并发。

不得不承认异步编程相比起同步编程的生态要小的很多,所以不可能完全异步编程,因此需要一种方式兼容。

多线程是为了兼容同步得代码。

多进程是为了利用CPU多核的能力。

输出如下:

可以看到总耗时1秒,说明所有的线程跟进程是同时运行的。

下面是本人使用过的一些异步库,仅供参考

web框架

http客户端

数据库

ORM

虽然异步库发展得还算不错,但是中肯的说并没有覆盖方方面面。

虽然我鼓励大家尝试异步编程,但是本文的最后却是让大家谨慎的选择开发环境,如果你觉得本文的并发,同步,兼容多线程,多进程不值得一提,那么我十分推荐你尝试以异步编程的方式开始一个新的项目,如果你对其中一些还有疑问或者你确定了要使用的依赖库并且大多数是没有异步库替代的,那么我还是建议你直接按照自己擅长的同步编程开始。

异步编程虽然很不错,不过,也许你并不需要。

有没有人写过python的一秒3000个并发请求的服务端

虽然没写过,但调查过。

我不知道你说的并发是指的单进程还是什么,如果不限定,前置用Nginx,后置N个web服务,连同一个数据库,那什么语言实现你这个级数的并发都是靠堆行硬件。如果是要单个进程达到3000,那么我的选择是用tornado,支持微线程,我做过实验静态网页可以做到3000并发

python协程并发量多少(python协程gevent)  第1张

python 多进程是真的并发吗

Python提供了非常好用的多进程包multiprocessing,你只需要定义一个函数,Python会替你完成其他所有事情。

借助这个包,可以轻松完成从单进程到并发执行的转换。

1、新建单一进程

如果我们新建少量进程,可以如下:

import multiprocessing

import time

def func(msg):

for i in xrange(3):

print msg

time.sleep(1)

if __name__ == \"__main__\":

p = multiprocessing.Process(target=func, args=(\"hello\", ))

p.start()

p.join()

print \"Sub-process done.\"12345678910111213

2、使用进程池

是的,你没有看错,不是线程池。它可以让你跑满多核CPU,而且使用方法非常简单。

注意要用apply_async,如果落下async,就变成阻塞版本了。

processes=4是最多并发进程数量。

import multiprocessing

import time

def func(msg):

for i in xrange(3):

print msg

time.sleep(1)

if __name__ == \"__main__\":

pool = multiprocessing.Pool(processes=4)

for i in xrange(10):

msg = \"hello %d\" %(i)

pool.apply_async(func, (msg, ))

pool.close()

pool.join()

print \"Sub-process(es) done.\"12345678910111213141516

3、使用Pool,并需要关注结果

更多的时候,我们不仅需要多进程执行,还需要关注每个进程的执行结果,如下:

import multiprocessing

import time

def func(msg):

for i in xrange(3):

print msg

time.sleep(1)

return \"done \" + msg

if __name__ == \"__main__\":

pool = multiprocessing.Pool(processes=4)

result = []

for i in xrange(10):

msg = \"hello %d\" %(i)

result.append(pool.apply_async(func, (msg, )))

pool.close()

pool.join()

for res in result:

print res.get()

print \"Sub-process(es) done.\"1234567891011121314151617181920

2014.12.25更新

根据网友评论中的反馈,在Windows下运行有可能崩溃(开启了一大堆新窗口、进程),可以通过如下调用来解决:

multiprocessing.freeze_support()1

附录(自己的脚本):

#!/usr/bin/python

import threading

import subprocess

import datetime

import multiprocessing

def dd_test(round, th):

test_file_arg = \'of=/zbkc/test_mds_crash/1m_%s_%s_{}\' %(round, th)

command = \"seq 100 | xargs -i dd if=/dev/zero %s bs=1M count=1\" %test_file_arg

print command

subprocess.call(command,shell=True,stdout=open(\'/dev/null\',\'w\'),stderr=subprocess.STDOUT)

def mds_stat(round):

p = subprocess.Popen(\"zbkc mds stat\", shell = True, stdout = subprocess.PIPE)

out = p.stdout.readlines()

if out[0].find(\'active\') != -1:

command = \"echo \'0205pm %s round mds status OK, %s\' /round_record\" %(round, datetime.datetime.now())

command_2 = \"time (ls /zbkc/test_mds_crash/) 2/round_record\"

command_3 = \"ls /zbkc/test_mds_crash | wc -l /round_record\"

subprocess.call(command,shell=True)

subprocess.call(command_2,shell=True)

subprocess.call(command_3,shell=True)

return 1

else:

command = \"echo \'0205 %s round mds status abnormal, %s, %s\' /round_record\" %(round, out[0], datetime.datetime.now())

subprocess.call(command,shell=True)

return 0

#threads = []

for round in range(1, 1600):

pool = multiprocessing.Pool(processes = 10) #使用进程池

for th in range(10):

# th_name = \"thread-\" + str(th)

# threads.append(th_name) #添加线程到线程列表

# threading.Thread(target = dd_test, args = (round, th), name = th_name).start() #创建多线程任务

pool.apply_async(dd_test, (round, th))

pool.close()

pool.join()

#等待线程完成

# for t in threads:

# t.join()

if mds_stat(round) == 0:

subprocess.call(\"zbkc -s\",shell=True)

break

python多线程并发数量控制

python多线程如果不进行并发数量控制,在启动线程数量多到一定程度后,会造成线程无法启动的错误。

控制多线程并发数量的方法有好几钟,下面介绍用queue控制多线程并发数量的方法。python3

python协程问题

你的理解完全错误: 1. timeout2秒不是2秒后才有回应,而是超过2秒后没有回应就会有异常, 你2秒后再回来检查??

2. 用协程可以写出异步IO的代码,一秒1000的并发都没问题,你根本就没理解什么是协程

另外,楼上的回答用多线程或多进程可以做,, 我建议使用多线程完成,,,,,多进程消耗资源太多,而且IO密集型的程序,不需要用到多CPU

结语:以上就是首席CTO笔记为大家整理的关于python协程并发量多少的全部内容了,感谢您花时间阅读本站内容,希望对您有所帮助,更多关于python协程并发量多少的相关内容别忘了在本站进行查找喔。

以上内容为新媒号(sinv.com.cn)为大家提供!新媒号,坚持更新大家所需的互联网后端知识。希望您喜欢!

版权申明:新媒号所有作品(图文、音视频)均由用户自行上传分享,仅供网友学习交流,不声明或保证其内容的正确性,如发现本站有涉嫌抄袭侵权/违法违规的内容。请发送邮件至 k2#88.com(替换@) 举报,一经查实,本站将立刻删除。

(0)
上一篇 2023-09-23
下一篇 2023-09-23

相关推荐

发表回复

登录后才能评论