python多线程、多进程、异步(协程)简单使用

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等线程安全数据类型都可以用来控制

你可能感兴趣的:(程序)