你知道吗? 在我的心里 你是多么的重要 就像 恩 请允许我来一段 freestyle 你们准备好了妹油 你看 这个碗 它又大又圆 就像 这条面 它又长又宽 你们 在这里 看文章 觉得 很开心 就像 我在这里 给你们 写文章 觉得很开心 skr~~ 不好意思 走错片场了 ok.. 接下来,就是 学习 python 的正确姿势 咱们在上一次的 python爬虫13 | 秒爬,这多线程爬取速度也太猛了,这次就是要让你的爬虫效率杠杠的 了解了一些 python 高效爬虫的概念 比如多线程、多进程、协程等 那么我们这一篇就开始了解多线程的具体使用 在 python 中 常用的多线程的模块有这么几个 _thread threading Queue 之前有个 thread 模块 被 python3 抛弃了 改名为 _thread 但其实 _thread 也没什么人用 因为 _thread 有的 threading 都有 _thread 没有的 threading 依然有 那么接下来我们就先来玩玩 threading 吧 在此之前 (请允许小帅b又开始吹水了~) 介绍一下 小帅b 的一点背景 小帅b呢 平常上班时间都会去河边摸鱼 每天得摸 20 条鱼 一条一条的摸 为的是什么 为的是安抚这些鱼的心情 这样以后送到餐前的红烧鱼才更加美味 恩 小帅b每天得摸 20 条鱼 每隔一秒钟摸一条 也就是这样 import time 后来 小帅b知道了多线程 拍脑一想 我靠 应该把小明和小红拉过来 让他们一起帮我摸鱼啊 也就是让小明和小红同时一人摸 10 条鱼 想想就开心 在 小帅b 的威逼利诱下 他们俩不情愿的手拉着手来到了河边 小帅b看小红是女生 就让小红每摸一条鱼休息 2 秒钟 而小明每摸一条鱼休息 1 秒钟 先扔一段代码给你 # encoding = utf-8 在这里呢 我们创建了一个线程类 然后继承 threading.Thread 在我们这个线程类里面定义了一个 run 方法 这个 run 方法去调用了摸鱼的方法 可以看到我们创建了两个线程 一个叫小明线程 一个叫小红线程 thread1 = MyThread(1, "小明", 1) 当我们的线程调用 start 方法的时候 它们就会去执行 run 方法 而我们用到的 join 方法呢 是为了让线程执行完 再终止主程序 运行一下就是这样 开始线程:小明 恩 小帅b再也不用摸鱼了 后来小明和小红都不乐意了 凭什么就我们两个摸鱼 这时候 小帅b 只能去找更多人了 连 小帅b 家的狗都叫过来了 然后 就疯狂的开启线程 thread1 = MyThread(1, "小明", 1) stop!!! 这可不行 因为频繁的创建线程 销毁线程 非常的浪费资源 所以呢 应该把他们放到池子里面去一起洗澡 哈,也就是 线程池 通过线程池就可以重复利用线程 不会造成过多的浪费 在 python 中 可以使用 ThreadPoolExecutor 来实现线程池 我们来往池子里塞 20 个线程 然后在循环的时候每次拿一个线程来摸鱼 def moyu_time(name, delay, counter): 运行一下 xiaoshuaib1 开始摸鱼 2019-03-10 23:30:10 可以看到 我们每次从线程池里面去拿一个线程来摸鱼 这样就不会去重复的创建销毁线程了 当然 我们还可以用一个叫做 Queue 的队列来创建线程池 队列嘛~ 就是可以往里塞东西 也可以往里拉东西 所以我们在使用队列的时候 最常用的方法就是 put 和 get 了 还是拿摸鱼为例 我们创建一个长度为 6 的队列 接着根据队列的长度创建了线程 每个线程都让它们处于守护状态 也就是需要的时候 马上执行 def queue_pool(): 接着我们就可以用 put 方法 把我们想做的事情往队列里面塞 比如这里我们想要摸鱼 for i in range(20): def moyu(): 要执行的话就需要去队列里面取了 q_method = self.__queue.get() 完整代码如下 import threading import time from queue import Queue
class CustomThread(threading.Thread): def __init__(self, queue): threading.Thread.__init__(self) self.__queue = queue
def run(self): while True: q_method = self.__queue.get() q_method() self.__queue.task_done()
def moyu(): print(" 开始摸鱼 %s" % (time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())))
def queue_pool(): queue = Queue(5) for i in range(queue.maxsize): t = CustomThread(queue) t.setDaemon(True) t.start()
for i in range(20): queue.put(moyu) queue.join()
if __name__ == '__main__': queue_pool() 本篇就到这里吧 ps:本来想接着写一下用多线程来爬取网站的,篇幅有限,咱们下一篇再见 peace 点个好看啊~~(破音) |
|