1、多线程、多进程
I/O密集(下载、读写文件)任务使用多线程
CPU密集任务使用多进程
import threading
def runner(p):
print(p)
t = threading.Thread(target=runner, args=('11',))
t.start()
t.join()
import multiprocessing
p = multiprocessing.Process(target=runner, args=('12',))
p.start()
p.join()
2、使用queue进行参数传递、获取结果
def runner(pq, rq):
while not pq.empty():
p = qp.get()
rq.put(p)
import queue
param_queue = queue.Queue()
result_queue = queue.Queue()
import threading
t = threading.Thread(target=runner, args=(param_queue, result_queue))
t.start()
t.join()
while not result_queue.empty():
print(result_queue.get())
from multiprocessing import Queue
3、线程池、进程池
param_list = ['12', '34', 'ab', 'ddd']
from multiprocessing.dummy import Pool as ThreadPool
with ThreadPool(10) as tp:
#不需要join,自带上下文管理
result = tp.map(runner, param_list)
print(result)
from multiprocessing import Pool as ProcessPool
4、异步
通常在服务器使用响应式架构,在python中称作协程,使用concurrent.futures执行异步操作
async、await两个关键字及asyncio模块,yield也是异步操作(交出CPU执行权限,next调用一次才return一次数据)
获取线程返回值,返回值顺序是随机的
def runner(p):
print(p)
return p
import concurrent.futures
with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
future_to_ret = []
future_to_ret.append(executor.submit(runner, '111'))
for future in concurrent.futures.as_completed(future_to_ret):
try:
print(future.result())
except Exception as exc:
print(' %s' % (exc))
5、速率控制(信号量限制并发数)
通常线程池会设置很大,但是有些服务在单位时间(10s)内被请求数过多,会封客户端ip。通过Semaphore可以控制
from threading import Semaphore
concurrency_num = Semaphore(10)
def runner(p):
###do a lot###
###do a lot end###
concurrency_num.acquire()
##send request##
concurrency_num.release()
return p
queue等线程安全数据类型都可以用来控制