Python并发编程实战

Python并发编程

本文是 Python并发编程实战 的课程笔记

学习官方文档网址:Python并发模块官方文档

01_简介

1、并发与并行

   ◆ 并发(concurrency) 指在同一时刻只能有一条指令执行,但多个进程指令被快速的轮换执行,使得在宏观上具有多个进程同时执行的效果,但在微观上并不是同时执行的,只是把时间分成若干段,使多个进程快速交替的执行。

   ◆ 并行(concurrency) 指在同一时刻,有多条指令在多个处理器上同时执行。所以无论从微观还是从宏观来看,二者都是一起执行的。
在这里插入图片描述

2、程序提速的方法


在这里插入图片描述
   ◆ 单线程串行:未利用任何并发技巧的编程方式,CPU需要等待IO,效率较低。(不加改造的naive的程序)
   ◆ 多线程并发:在某个线程进行IO时,CPU可以调度另一个线程进行计算,提高了CPU利用率。实际上仍然是一个CPU核心进行分时调度。(threading)
   ◆ 多CPU并行:需要多核CPU,可以并行地处理多个线程,充分利用现代CPU的多核性能。(multiprocessing)
   ◆ 多机器并行:分布式计算,多机器并行。(hadoop/hive/spark)

3、Python对并发编程的支持


   ● 多线程:threading,利用CPU和IO可以同时执行的原理,让CPU不会干巴巴等待IO完成
   ● 多进程:multiprocessing,利用多核CPU的能力,真正的并行执行任务
   ● 异步IO:asyncio,在单线程利用CPU和IO同时执行的原理,实现函数异步执行

   ● 使用Lock对资源加锁,防止冲突访问
   ● 使用Queue实现不同线程/进程之间的数据通信,实现生产者 - 消费者模式
     使用线程池Pool/进程池Pool,简化线程/进程的任务提交、等待结束、获取结果
   ● 使用subprocess启动外部程序的进程,并进行输入输出交互

02_怎样选择多线程多进程多协程

1、CPU密集型计算、IO密集型计算
CPU密集型(CPU-bound)

CPU密集型也叫计算密集型,是指I/O在很短的时间就可以完成,CPU需要大量的计算和处理,特点是CPU占用率相当高。
例如:压缩解压缩、加密解密、正则表达式搜索

IO密集型(IO-bound)

IO密集型指的是系统运作大部分的状况是CPU在等I/O(硬盘/内存)的读/写操作,CPU占用率仍然较低。
例如:文件处理程序、网络爬虫程序、读写数据程序

2、多线程、多进程、多协程的对比

三个是级联关系:一个进程中可以启动N个线程,一个线程中可以启动N个协程。

多线程 Thread(threading)
  • 优点:相比进程,更轻量级、占用资源少
  • 缺点
    • 相比进程:多线程只能并发执行,不能利用多CPU(GIL)
    • 相比协程:启动数目有限制,占用内存资源,有线程切换开销
  • 适用于:IO密集型计算、同时运行的任务数目要求不多
多进程 Process(multiprocessing)
  • 优点:可以利用多核CPU并行运算
  • 缺点:占用资源最多,可启动数目比线程少
  • 适用于:CPU密集型计算
多协程 Coroutine(asyncio)
  • 优点:内存开销最少、启动协程数量最多
  • 缺点:支持的库有限制(aiohttp vs requests)、代码实现复杂
  • 适用于:IO密集型计算、需要超多任务运行、但有现成库支持的场景
3、根据任务如何选择对应技术

在这里插入图片描述

03_全局解释器锁(GIL)

1、Python速度慢的两大原因
  • 1、Python是动态类型语音,边解释边执行
  • 2、Cpython中的全局解释器锁GIL,使得无法利用多核CPU并行执行
2、GIL

全局解释器锁(GIL) 是计算机程序设计语言解释器用于同步线程的一种机制,它使得任何时刻仅有一个线程在执行。即便在多核心处理器上,使用GIL的解释器也只允许同一时间执行一个线程。


在这里插入图片描述

由于GIL的存在
即使电脑有多核CPU
单个时刻也只能使用1个
相比并发加速的C++/JAVA所以慢

3、为什么有GIL这个东西

绝大部分处理器都是单核心的,考虑不到并行的问题,而为了解决多线程之间数据完整性和状态同步的问题,引入了 GIL。

GIL有好处:
简化了Python对共享资源的管理

4、怎样规避GIL带来的限制

1.多线程threading机制依然是有用的,用于IO密集型计算

 因为在I/O(read,write,send,recv,etc.)期间,线程会释放GIL,实现CPU和IO的并行
 因此多线程用于IO密集型计算依然可以大幅提升速度

 但是多线程用于CPU密集型计算时,只会更加拖慢速度

2.使用multiprocessingde 多进程机制实现并行计算、利用多核CPU优势

 为了应对GIL的问题,Python提供了multiprocessing

04_使用多线程

1、Python创建多线程的方法
  • 1、准备一个函数
def my_func(a,b):
	do_craw(a,b)
  • 2、怎样创建一个线程
import threading
t = threading.Thread(target=my_func,args=(100,200))
  • 3、启动线程
t.start()
  • 4、等待结束
t.join()
2、改写爬虫程序,变成多线程爬虫

blog_spider.py

import requests

urls = [
    f"https://www.cnblogs.com/#p{
     page}"
    for page in range(1,50+1)
]

def craw(url):
    r = requests.get(url)
    print(url,len(r.text))

01.multi_thread_craw.py

import blog_spider
import threading
import time

def single_thread():
    print("single_thread begin")
    for url in blog_spider.urls:
        blog_spider.craw(url)
    print("single_thread end")

def multi_thread():
    print("multi_thread start")
    threads = []   #存放thread对象
    for url in blog_spider.urls:
        threads.append(threading.Thread(target=blog_spider.craw,args=(url,)))

    for thread in threads:
        thread.start()

    for thread in threads:
        thread.join()

    print("multi_thread end")

if __name__ == '__main__':
    start = time.time()
    single_thread()
    end = time.time()
    print("single thread cost:",end - start,"seconds")

    start = time.time()
    multi_thread()
    end = time.time()
    print("multi thread cost:", end - start, "seconds")

05_Python实现生产者消费者爬虫

1、多组件的Pipeline技术架构


在这里插入图片描述

2、生产者消费者爬虫的架构


在这里插入图片描述

3、多线程数据通信的queue.Queue

queue.Queue可以用于多线程之间的、线程安全的数据通信

#1、导入类库
import queue

#2、创建Queue
q = queue.Queue()

#3、添加元素
q.put(item)

#4、获取元素
item = q.get()

#5、查询状态

#查看元素的多少
q.qsize()
#判断是否为空
q.empty()
#判断是否已满
q.full()
4、代码编写实现生产者消费者爬虫

blog_spider.py

import requests
from bs4 import BeautifulSoup

urls = [
    f"https://www.cnblogs.com/#p{
     page}"
    for page in range(1,50+1)
]

def craw(url):
    r = requests.get(url)
    return r
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值