协程并发遇到的坑

499 阅读2分钟

任务需求

  • 1、请求25万个url,并且判断目标的url是否有正常页面
  • 2、将正常的页面url进行数据库数据存储

完成任务思路

1、线程池

定义请求的函数,根据主机的cpu情况定义线程池的数量然后,然后将任务提交到线程池当中,线程池会自动根据池子的数量大小然后url多线程执行任务操作 2、进程池 定义请求的函数,根据主机的cpu情况定义进程池的数量然后,然后将任务提交到进程池当中,线程池会自动根据池子的数量大小然后url多进程程执行任务操作

协程

出现的问题

提示原因:协程当中全部执行,但是有些是执行失败的,实际上并没有进行重新处理,所以需要限定协程数量为好,并且换用gather来,按照顺序批量处理协程

于是代码可以改为这样:

假如你的并发达到2000个,程序会报错:ValueError: too many file descriptors in select()。报错的原因字面上看是 Python 调取的 select 对打开的文件有最大数量的限制,这个其实是操作系统的限制,linux打开文件的最大数默认是1024,windows默认是509,超过了这个值,程序就开始报错。

解决办法

1、限制协程的最大并发数量(Linux为1024,Window为509) 推荐方式

2、使用回调的方式

3、修改操作系统打开文件数的最大限制,在系统里有个配置文件可以修改默认值

下图为通过控制协程的并发数来解决:

另外一种解决办法,也是类似线程和进程一样创建一个池子来解决,gevent便提供了协程池

from gevent.pool import Pool
import gevent.monkey
gevent.monkey.patch_all()