今天在帮一个兄弟找bug的时候发现了一个与理论知识有点出入的地方,觉得还蛮有意思就分享一下。
这篇文章主要解释的是pool中map函数的运用,函数的主题是一个爬虫,显示的结果就是爬取的页面提示,全部代码会在最后给大家附上,可以自己尝试。
大家都知道map的函数原型为:
map(func, iterable[, chunksize=None]),其中iterable就是迭代器。
Pool类中的map方法,与内置的map函数用法行为基本一致,它会使进程阻塞直到结果返回,这是大众对于map函数的理解,所以基本产生的结果就是顺序执行。但结果真是这样吗?
1.首先来看看在迭代次数很大时的效果:
1
可以看到由于池的数量和需要迭代的数量差距很大,所以存在资源的争夺,即使程序的执行速度很快,每个池的平均子进程数也是55,所以不会出现循序执行的结果。
2.迭代次数不变,进程池数量默认。2
我们可以看到开始的时候也不是顺序执行的,这里就会引入一些假设:
1.第二个参数是一个迭代器,但在实际使用中,必须在整个队列都就绪后,程序才会运行子进程
2.默认的进程池数量并不是1
要验证上面两种假设,就需要进行下面的步骤。.
3.限定进程池的数量3
霍,果然就是这样,不过因为只有一个池,程序执行的速度大大减慢了。写到这里我们可以继续往下挖一挖,看看每个池平均有几个进程时不会严重影响到程序的执行顺序,换句话说资源的争夺在一个池的进程执行完后才开始。
4.比例为4的时候(5在最上面)。4
5
当比例为4的时候,可以看到开始的时候基本会有一点小乱序,但后面基本就是顺序了,这个结果基本就很好了,再就是看看3的话是什么效果。
5.比例为36
果然,比例为三的时候基本就没有乱序了,同时速度也很快。但是其实使用像Lock等进程锁的话基本就不会出现乱序的问题,但从这件事中,不能盲目相信官方的解释。哈哈哈
另外我也在ipython中看了Pool的相关解释,并没有发现默认进程池的数量,也许就是随机的吧,但很少会是1.
后续我会继续更新自己在程序设计中的一些心得,希望能够帮到大家,为大家解决疑惑。
写于2018年9月3号