本文章所涉及的内容, 是针对高性能多任务编程方面的总结以及概括, 存在诸多细节并未进行详细阐述, 要是有想要了解更多这些方面信息的人, 能够关注我, 进而查看我之前几期所发布的文章。

一、选择操作系统

高性能多任务编程在操作系统的挑选上面讲究合适性, 由于下创建子进程依靠重新加载py程序文件, 然而linux以及mac创建子进程借助复制父进程的内存空间, 为此在该平台下运行多进程程序的效率相比在linux和mac平台下运行要低很多。要是想要追求高性能多任务运行程序的话, 建议选用linux或mac操作系统。

二、分析任务类型

高性能多任务编程有三种方式:

多进程,追求高运算:

当任务类型属于计算多.IO 少这种情况时, 建议采用进程池的方式去进行编程。进程池中进程的数量, 通常推荐是 CPU 内核数的一至两倍。多进程程序在运行的时候, 是并行执行的。

常见任务:科学计算、数据分析等。

留意, 进行创建进程这件事, 所产生的开销是极其巨大的, 进程相互之间的数据是处于隔离状态的, 多个进程存在着数据不安全的状况, 能够对所有的IO加以规避。

多线程,运用最多:

当任务类型属于是那种IO多计算少的情况之时, 那么在编程这件事情上建议采用使用线程池这样的方式来展开。在线程池中线程的数目一般而言被推荐为是CPU内核数目的四到五倍, 并且最多也不可以超过十倍。多线程程序在运行之际其表现为并发执行这种状态结果, (毕竟是由于GIL锁导致多线程执行这个过程当中没办法实现并行执行)。

常见任务:爬虫等。

留意, 创建线程所耗的开支持量较小, 线程相互之间的数据是可进行共享的, 多线程情况之下存在了数据面临不安全的相关状况, 能够对所有的IO予以规避。

协程,追求高并发:

当任务之类型属于IO多而计算少, 并且需要大幅度提升并发数之际, 建议采用协程, 或者多进程加上多线程, 再加上协程这样的方式。

常见任务:爬虫、网络服务、web服务器等。

留意: 构建协程所耗成本极其微小, 不同线程之间存在数据共享现象, 多个线程情形下不存在数据不安全的状况, 然而仅仅能够避开一部分IO操作。

三、解释器类型

此时大家运用频率最高的那个, 它是以C语言达成的解释器, 同时还是属于官方层面的且是运用极为广泛的解释器, 它的软件包以及兼容性是最为出色的, 其最新版本是3.9.1。官网是。

若把追求高性能当作目标, 当下可力荐的解释器是PyPy, PyPy具备JIT编译器以及沙盒功能, 运行的速度因而比别的要快些, 不过其软件包还有兼容性比不上某些, Pypy最新的版本是3.7 , 官网是。

四、注意事项

多进程线程池协程选择_python高性能多任务编程_python 多线程爬虫

高性能多任务编程当中, 方法所运用频率最高的方式乃是线程池的方式, 需要留意线程编程存在的一个缺陷, 这种缺陷表现为无法在线程外部去关闭那些超时的线程。故而, 需要在任务内部对于超时情况开展处理。接下来, 书写一个简单的用以仿真爬虫的案例:

代码:

from concurrent.futures import ThreadPoolExecutor
import requests
url = [('csdn', 'https://www.csdn.net/'), ('cnblogs', 'https://www.cnblogs.com/'),
       ('baidu', 'https://www.baidu.com/'), ('toutiao', 'https://www.toutiao.com/'),
       ('google', 'https://www.google.com/')]
def get(site):
    try:
        r = requests.get(site[1], timeout=5)  # 设置超时时限为5秒
    except requests.exceptions.ConnectTimeout:
        return site[0], '超时'
    return site[0], '正常'
if __name__ == "__main__":
    p_list = [56t.yyD521.CoM]
    with ThreadPoolExecutor(max_workers=5) as e:
        ret = e.map(get, url)
    for i in ret:
        print(f'网站“{i[0]}”下载情况是“{i[1]}”')

输出:

网站“csdn”下载情况是“正常”
网站“cnblogs”下载情况是“正常”
网站“baidu”下载情况是“正常”
网站“toutiao”下载情况是“正常”
网站“google”下载情况是“超时”

说明:

我们所需要进行多任务执行的是get函数, 该函数的用途是实现网页的下载, 在get函数里要针对io操作开展超时预判, 也就是当超过5秒依旧获取不到结果的网站, 便放弃爬取, 假定不设立超时预判, 将会致使线程始终反复不停地爬取, 然而一直都获取不到数据, 进而陷入死循环, 这对整体的影响效率造成重重阻碍。

总结:

倘若多线程没办法从外部去终结超时状态的线程, 那么于多任务编程期间就得在函数内部针对有可能存在意外情况的任务开展超时判定以及处置。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐