适用前景
CPU密集的程序适合使用多线程,可充分利用计算机的多核
多线程应用场景
1、IO操作多的程序适合使用多线程,包括网络IO、本地磁盘IO
2、爬虫发请求等响应:网络IO
3、爬虫处理所抓取数据:本地磁盘IO
4、所有使用多线程编写爬虫能够极大提升数据抓取的效率
queue(队列模块)
安装
from queue import Queue
避免阻塞的3种方式
1:q.get(block=False)
2:q.get(block=True, timeout=3)
3:while not q.empty():
q.get()
threading模块
安装
from thread import Thread
t = Thread(target=事件函数名)
t.start()
t.join()
创建多线程
from threading import Thread
# 线程函数
def spider():
pass
t_list = []
for i in range(5):
t = Thread(target=spider)
t_list.append(t)
t.start()
for t in t_list:
t.join()
线程锁
导入线程锁
from threading import Lock
啥时候加锁
当多个线程操作同一个共享资源的时候
使用方法
创建锁:lock=Lock()
上锁:lock.acquire()
释放锁:lock.release()
当上锁成功后,未释放锁之前,再次上锁会阻塞
例子
未上锁
from threading import Thread,Lock
n = 5000
def f1():
global n
for i in range(1000000):
n += 1
def f2():
global n
for i in range(1000000):
n -= 1
t1 = Thread(target=f1)
t1.start()
t2 = Thread(target=f2)
t2.start()
print(n)
t1.join()
t2.join()
运行后的结果每次都不一样,具有随机性
上锁
from threading import Thread,Lock
n = 5000
lock = Lock()
def f1():
global n
for i in range(1000000):
lock.acquire()
n += 1
lock.release()
def f2():
global n
for i in range(1000000):
lock.acquire()
n -= 1
lock.release()
t1 = Thread(target=f1)
t1.start()
t2 = Thread(target=f2)
t2.start()
t1.join()
t2.join()
print(n)
运行后的结果就是n(5000)了,不管运行多少次都是5000