Python网络爬虫案例实战:并发与 Web:并发和并行、同步和异步、阻塞与非阻塞

Python网络爬虫案例实战:并发与 Web:并发和并行、同步和异步、阻塞与非阻塞

Python 支持的并发分为多进程并发与多线程并发。概念上来说,多进程并发即运行多个独立的程序,优势在于并发处理的任务都由操作系统管理,不足之处在于程序与各进程之间的通信和数据共享不方便;多线程并发则由程序员管理并发处理的任务,这种并发方式可以方便地在线程间共享数据(前提是不能互斥)。Python对多进程和多线程的支持都比一般编程语言更高级,最大限度地减少了需要我们完成的工作。

6.1并发和并行、同步和异步、阻塞与非阻塞

在介绍多线程爬虫之前,首先需要熟悉并发和并行、同步和异步、阻塞与非阻塞的概念。

6.1.1并发和并行

并发(concurrency)和并行(parallelism)是两个相似的概念。引用一个比较容易理解的说法,并发是指在一个时间段内发生若干事件的情况,并行是指在同一时刻发生若干事件的情况。
这个概念用单核CPU(见图6-1)和多核 CPU(见图6-2)比较容易说明。在使用单核CPU时,多个工作任务是以并发方式运行的,因为只有一个CPU,所以各个任务会分别占用 CPU的一段时间依次执行。如果在自己分得的时间段没有完成任务,就会切换到 CPU的一段时间依次执行。如果在自己分得的时间段没有完成任务,就会切换到另一个任务,然后在下一次得到 CPU 使用权的时候再继续执行,直到完成。在这种情况下,因为各个任务的时间段很短、经常切换,所以给我们的感觉是“同时”进行。在使用多核 CPU时,在各个核的任务能够同时运行,这是真正的同时运行,也就是并行。
并行情况:CPU核心数量大于或等于进程数量。
在这里插入图片描述
在这里插入图片描述
以吃一碗米饭和一盘菜的任务为例,“并发”就是一个人吃,这个人吃一口菜然后吃一口饭,由于切换速度比较快,让你觉得他在“同时”吃菜和吃饭;“并行”就是两个人同时吃,一个人吃饭,一个人吃菜。
下面以两个例子来进一步说明。例如:
[例6-1]创建两个线程,演示并发和并行效果1。

import threading #线程
import time
def music():
    print('begin to listen music {}'.format(time.ctime()))
    time.sleep(3)
    print('stop to listen music {}'.format(time.ctime()))

def game():
    print('begin to play game {}'.format(time.ctime()))
    time.sleep(5)
    print('stop to play game {}'.format(time.ctime()))

if __name__ == '__main__':
    music()
    game()
    print('ending.....')

输出:

begin to listen music Tue Aug 13 15:02:52 2024
stop to listen music Tue Aug 13 15:02:55 2024
begin to play game Tue Aug 13 15:02:55 2024
stop to play game Tue Aug 13 15:03:00 2024
ending.....

music的时间为3s,game的时间为5s,如果按照正常的方式执行,直接执行函数,那么将按顺序执行,整个过程为8s。
[例6-2]创建两个线程,演示并发和并行效果2。

import threading #线程
import time
def music():
    print('begin to listen music {}'.format(time.ctime()))
    time.sleep(3)
    print('stop to listen music {}'.format(time.ctime()))

def game():
    print('begin to play game {}'.format(time.ctime()))
    time.sleep(5)
    print('stop to play game {}'.format(time.ctime()))

if __name__ == '__main__':
    t1 = threading.Thread(target=music) #创建一个线程对象t1 子线程
    t2 = threading.Thread(target=game) #创建一个线程对象t2 子线程
    t1.start()
    t2.start()
    # t1.join() #等待子线程执行完 t1不执行完,谁也不准往下走
    t2.join()
    print('ending.......') #主线程
    print(time.ctime())

输出:

begin to listen music Tue Aug 13 15:05:21 2024
begin to play game Tue Aug 13 15:05:21 2024
stop to listen music Tue Aug 13 15:05:24 2024
stop to play game Tue Aug 13 15:05:26 2024
ending.......
Tue Aug 13 15:
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值