程序员用一个爬虫的案例,多线程的掌握

在多线程编程出现之前,电脑程序的运行由一个执行序列组成,执行序列按顺序在主机的CPU中运行。无论是任务本身要求顺序执行还是整个程序是由多个子任务组成,程序都是按这种方式执行的。即使子任务相当独立,相互无关(即,一个子任务的结果不影响其他子任务的结果)。这样并行处理可以大幅度地提升整个任务的效率,这也就是多线程编程的什么是线程目的。

线程(有时被称为轻量级进程)跟进程有些相似,不同的是,所有的线程运行在同一个进程,共享相同的运行环境。

线程有开始,顺序执行和结束三部分。它有自己的指令指针,记录自己运行到什么地方。线程的运行可能被抢占(中断),或暂时挂起(也叫睡眠),让其他的线程运行(也叫让步)。一个进程中的各个进程之前共享同一片数据空间,所以线程之间可以比进程之间更方便的共享数据和之间的互相通讯。

全局解释器锁(GIL)

Python代码的执行由Python虚拟机(也叫解释器主循环)来控制。Python在设计之初就考虑到在主循环中,同时只有一个线程在运行,就像在单CPU的系统中运行多个进程那样,尽管在内存中可以存放多个程序,但是在任意时刻,只有一个程序在CPU中运行。

对于Python虚拟机的访问由GIL来控制,正是这个锁能保证同一时刻只有一个线程在运行。在多线程的环境中,Python虚拟机按一下方式运行:

  • 设置GIL

  • 切换到一个线程中运行

  • 运行: a. 指定数量的字节码的指令,或者线程主动让出控制(可以调用time.sleep(0))

  • 把线程设置为睡眠状态

  • 解锁GIL

  • 重复以上所用步骤

    编写扩展程序的程序员可以主动解锁GIL,不过Python的开发人员则不用担心在这个情况下你的Python代码会被锁住。

    例如,对所有面向I/O的程序来说,GIL会在这个I/O调用之前被释放,以允许其他的线程在这个线程等待I/O的时候允许。如何某线程并未使用很多I/O操作,它会在自己的时间片内一直占用CPU和GIL,也就是说,I/O密集型的Python程序比计算密集型的程序更能充分利用多线程环境的好处

没有线程支持的情况

示例1

在单线程中顺序执行两个循环。一个循环结束后,另一个才能开始。总的时间是各个循环运行的时间之和。

#!/usr/bin/env pythonfrom time import sleep, ctimedef loop0():

执行结果:loop0和loop1各自运行了4秒和2秒,整个程序耗时6秒,属于串行执行

程序员用一个爬虫的案例给我看,看完我对多线程基本全部掌握!

运行结果

Python的threading模块

Python提供了几个用于多线程编程的模块,包括threadthreadingQueue等。

  • thread模块提供了基本的线程和锁的支持

  • threading提供了更高级、功能更强的线程管理的功能

  • Queue模块允许用户创建一个可以用于多个线程之间共享数据的队列数据结构。

示例2深圳万利胶盒包

#!/usr/bin/env pythonimport threadfrom time import sleep, ctimedef loop0():

执行结果:loop0和loop1并行执行,2个函数执行耗时4秒

程序员用一个爬虫的案例给我看,看完我对多线程基本全部掌握!

image.png

示例3

使用线程和锁

引入锁的概念是为了线程不用什么时候结束再做额外的等待,使用了锁,我们就可以在两个线程都退出后,马上退出。(线程管理)

#!/usr/bin/env pythonimport threadfrom time import sleep, ctime

执行结果:

程序员用一个爬虫的案例给我看,看完我对多线程基本全部掌握!

image.png

示例4

使用threading模块的Thread类的一个join(),允许主线程等待子线程的结束

#!/usr/bin/env pythonimport threadingfrom time import sleep, ctime

执行结果: 所有的线程先都创建好之后,再一起调用start()函数启动,而不是创建一个启动一个,而且不需要在管理一堆锁(分配锁、获得锁、释放锁、检查锁等),只需简单地对每个线程调用join()函数就可以了。

程序员用一个爬虫的案例给我看,看完我对多线程基本全部掌握!

image.png

示例5

线程池threadpool模块

import timefrom multiprocessing.dummy import Pool as ThreadPool

程序员用一个爬虫的案例给我看,看完我对多线程基本全部掌握!

image.png

示例6

多线程爬取京东手机信息

#!/usr/bin/env python# -*- coding: utf-8 -*-import sysimport timeimport jsonimport requestsfrom lxml import etreefrom pymongo importMongoClientfrom multiprocessing.dummy import Pool as ThreadPool

程序员用一个爬虫的案例给我看,看完我对多线程基本全部掌握!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值