Python进阶-多线程和多进程(持续更新)

Python的线程有个经典问题,GIL(全局控制锁,即Python在某一时刻只能有一个线程运行),那多线程是怎么来的呢?实现方法?

答:在I/O密集型任务处理中,等待请求时,Python中的I/O函数会自动释放GIL,再运行一个线程,所以会缩短I/O时间,属于并发操作。实现方法有concurrent.future模块(futures.ThreadPoolExecutor类),threading模块。

Python可以实现真正的并行吗?多进程又是什么鬼呢?多进程一定会更快吗?

答:这倒是可以,可以选择CPU数量执行并行任务,这样就可以执行多进程任务。并行操作的多进程不一定比多线程快,二者适用领域不同,多进程适合CPU密集型(进行大量的数值计算,全部在运行内存中进行)操作,多线程适合I/O密集型(与磁盘有交互行为)操作。实现方法有threading模块,mutiprocessing模块,futures.ProcessPoolExecutor类。

 下面先实现一个多线程吧,这样好像简单一点。

In [65]: import requests

In [66]: import tqdm

In [67]: import os

In [68]: import time

In [69]: import sys

In [70]: POP_CC= ('CC,IN,US,ID,BP').split()

In [71]: BASE_URL = 'http://flupy.org/data/flags'

In [72]: DEST_DIR = 'downloads/'

In [73]: def save_flag(img,filename):
    ...:     path = os.path.join(DEST_DIR,filename)
    ...:     with open(path,'wb') as fp:
    ...:         fp.write(img)
    ...:

In [74]: def get_flag(cc):
    ...:     url = '{}/{cc}/{cc}.gif'.format(BASE_URL,cc=cc.lower())
    ...:     resp = requests.get(url)
    ...:     return resp.content
    ...:

In [75]: def show(text):
    ...:     print(text,end='')
    ...:     sys.stdout.flush()
    ...:

In [76]: def download_one(cc): # 技巧,所有基操都放在一个里
    ...:     image = get_flag(cc)
    ...:     show(cc)
    ...:     save_flag(image,cc.lower()+'.gif')
    ...:     return cc
    ...:

In [77]: MAX_WORKERS = 20 # 20个线程

In [78]: def download_many(cc_list):
    ...:     workers = min(MAX_WORKERS,len(cc_list)) # 任务少的话开多没用
    ...:     with futures.ThreadPoolExecutor(workers) as executor:
    ...:         res = executor.map(download_one,tqdm.tqdm(sorted(cc_list))) # 其实经历了future实例的过程,可以细究,不过单纯实现不需要知道,tqdm显示进度条
    ...:     return len(list(res))
    ...:

In [79]: def main(download_many):
    ...:     t0 = time.time()
    ...:     count = download_many(POP_CC)
    ...:     elapsed = time.time()-t0
    ...:     msg = '\n{} flags downloaded in {:.2f}s'
    ...:     print(msg.format(count,elapsed))
    ...:

In [80]: if __name__ == 'main':
    ...:     main(download_many)

猜你喜欢

转载自blog.csdn.net/weixin_40539952/article/details/107488111