多线程爬虫
关注:程序的运行速度主要是由cpu来决定的。想要提高程序的运行速度,就得提高cpu 的利用率
提高cpu利用率的两种途径:
- 让cpu不休息。cpu每时每刻都在处理任务,这个任务可以理解为线程。这种情况就叫做多线程。
- cpu都是分核。每个核就好比一个小脑袋。可以理解为一心多用。让每个核都作用起来,去干不同的事情,这种方法叫做多进程
一、程序、线程、进程?
- 程序:一个应用就可以理解为一个程序。
- 进程:程序运行资源分配的最小单位,一个程序可以有多个进程
- 线程:cpu最小的调度单位,必须依赖进程存在,线程是没有独立资源的,所有的线程共享他所在进程的所有资源
二、什么是多线程?
- 程序中包含多个并行的线程来完成不同的任务
三、python中的threading模块
1、创建多线程的第一种方法:
t = threading.Thread(
target = 方法名,
args = (,)--参数列表,元组
)
t.start()---启动线程
2、查看线程的数量:threading.enumerate()
enumerate(
可迭代对象,
i,----表示索引从i开始
)----python的内置函数:枚举可迭代对象,同时获取迭代对象的每个值和其索引
可迭代对象:有__iter__属性的对象
迭代器:有__iter__和__next__属性的对象
这两个如何转化:迭代器=iter(可迭代对象)
可迭代对象都有:list,tuple,dict,str,bytesarray,set,fp
3、创建第二种方法:自定线程类
python的继承:
(1)继承是通过在定义类的时候,类后面的()中增加父类来实现的
(2)被继承的类称为父类,继承的类称为子类
(3)子类继承父类所有非私有的属性及方法
(4)如果子类重写父类的属性和方法,子类默认是优先拿自己的。
用自定义线程的步骤:
(1)继承threading.Thread
(2)重写run方法
(3)实例化这个类,就相当于创建了一个线程
t = MyThread()
t.start()---默认执行就是run方法里面的内容
(4)如果自定义线程要传参数,这时候必须要写init方法,必须在init中先调用父类的init(初始化父类)
调用父类的init方法有两种:
super().__init__()
threading.Tread.__init__(self)
4、线程的名称:线程.name查看线程的名称
如果没有给线程自定义名称,默认线程的名称是:Thread-1,Thread-2……
自定义名称:
t = MyThread(name=str(i))
t.start()
5、线程的五种状态:
线程的执行顺序是混乱的:线程是cpu调度的最小单位,线程的执行完全是由cpu调度所决定的。cpu的调度,是由线程状态决定的
6、线程间公用数据的共享问题。
多个线程多全局变量的更改,容易造成数据的混乱。
解决办法:
将线程对公有数据更改部分,用互斥锁锁起来,这就可以解决这种问题。
多线程避免多个线程同时处理公有变量。---解耦
import threading
mutex = threding.Lock() # 创建一个锁对象
if mutex.acquere(): # 上锁
'''
公有数据的处理代码
'''
mutex.acquere(True):默认情况就是True,线程到锁这里如果没有获取锁状态,就会被阻塞。
mutex.acquire(False):线程到锁这里如果没有获取锁状态,不会被阻塞。