Python爬虫——多线程(一)
一、多线程概述
多进程
pycharm 腾讯课堂 浏览器
n个cpu核心 可以同时执行多个任务
多线程
线程 进程中的执行单位就是线程(进程中所包含的执行单位就是线程)
一个进程可以包含多个线程
在python中 实际上一次只能执行一个线程
存在线程锁 用来解决资源竞争的问题
用多线程爬虫的优势?
主要用来解决效率问题
I/O操作 input
onput
网络IO 磁盘IO
需要把多线程需要完成的工作写入到事件函数中
可以同时进行多个线程的事件
二、多线程的创建
1.通过函数创建
import threading
import time
def demo():
# 线程的事件函数
print('子线程')
if __name__ == '__main__':
# target用来传函数 函数名后面不能跟括号
# threading.Thread(target=demo())
for i in range(5):
t = threading.Thread(target=demo()) # target用来接收函数事件的 args=()用来传参的
# 启动(给一个可以启动的状态)
t.start()
2.类创建多线程
import threading
import time
# 通过类创建多线程
# 自定义的MyThread类需要继承父类 threading.Thread
class MyThread(threading.Thread):
# def run(self) -> None 表示run函数的返回值为空
def run(self) -> None:
for i in range(5):
print('子线程')
if __name__ == '__main__':
m = MyThread()
# m.run() 是一个简单的方法调用
# m.run()
m.start()
线程锁
利用线程锁解决资源竞争问题
得先找到可能会出现资源竞争问题得地方找到之后给这个可能得地方上把
锁
上锁要记得解锁不然可能会导致资源竞争的问题
队列存放我们待爬取的url
threading.lock()
创建锁
threading.Rlock()
创建锁,可以多个上锁
import threading
import time
# threading.enumerate()
# 创建锁
# lock = threading.Lock()
# 可以上多把锁,上了几把锁就需要解几把锁
lock = threading.RLock()
num = 100
def demo1(nums):
global num
lock.acquire() # 上锁
lock.acquire()
for i in range(nums):
num += 1
lock.release()
lock.release() # 解锁
print('demo1--{}'.format(num))
def demo2(nums):
global num
lock.acquire()
for i in range(nums):
num += 1
lock.release()
print('demo2--{}'.format(num))
def main():
# 传递函数事件
# args 用来传参的 传递的是元组 哪怕只传递一个参数 后面也要有逗号
t1 = threading.Thread(target=demo1, args=(1000000,))
t2 = threading.Thread(target=demo2, args=(1000000,))
t1.start()
t2.start()
time.sleep(3)
print('main--{}'.format(num))
if __name__ == '__main__':
main()