最近在做爬虫,语音,视频合成,需要使用多线程,多进程的模型。做个学习使用记录。
使用多线程还是使用多进程,怎么样来控制防止线程太多,导致线程失控,就是请求一个任务,生成一个进程,最终导致进程暴涨,进而无法控制。所以,对于任务数量一直在增加的程序,固定线程数量的线程池是必要的。
-
一些说明:
- 单进程因为处理过程中因为io或者密集计算导致延迟太多,耗时太多,运行一次太累。
- 使用多线程,多进程能一定程度的上解决这个问题,但是需要多少个线程(进程)这个需要详细的测试。
-
最佳线程数的获取:
-
过用户慢慢递增来进行性能压测,观察QPS(即每秒的响应请求数,也即是最大吞吐能力。),响应时间
-
根据公式计算:服务器端最佳线程数量=((线程等待时间+线程cpu时间)/线程cpu时间) * cpu数量
-
单用户压测,查看CPU的消耗,然后直接乘以百分比,再进行压测,一般这个值的附近应该就是最佳线程数量。
-
-
对于io密集型模型
- 网络io密集型线程和进程没有明显的一个差别,因为影响性能的主要在网络延迟
- 磁盘的io密集型多线程性能要优于多进程
- 自己写多线程模块
- python2,3中的多线程使用threadpool这个第三方模块,模块比较老了,用的人不多了
- python3中自带的模块concurrent.futures
主要说明第三种:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from concurrent.futures import ThreadPoolExecutor
import time
def get_content(url, type=1):
# print('begin')
time.sleep(2)
return 'url:{},type:{}'.format(url, type)
max_workers = 4
# 创建进程池
handler = ThreadPoolExecutor(max_workers=max_workers)
# f1 = handler.submit(get_content,'baidu.com',1)
# f2 = handler.submit(get_content,'movie.com',2)
urls = ['baidu.com','movie.com']
results = handler.map(get_content,urls)
for ret in results:
if ret.running():
print('ret:{},running'.format(ret))
进程池客户使用submit或者map函数批量提交