我们这一篇就开始了解多线程的具体使用
在 python 中
常用的多线程的模块有这么几个
_thread
threading
Queue
之前有个 thread 模块
被 python3 抛弃了
改名为 _thread
但其实 _thread 也没什么人用
因为 _thread 有的 threading 都有
_thread 没有的 threading 依然有
那么接下来我们就先来玩玩 threading 吧
在此之前
介绍一下 小编 的一点背景
小编呢
平常上班时间都会去河边摸鱼
每天得摸 20 条鱼
一条一条的摸
为的是什么
为的是安抚这些鱼的心情
这样以后送到餐前的红烧鱼才更加美味
恩
小编每天得摸 20 条鱼
每隔一秒钟摸一条
也就是这样
后来
小编知道了多线程
拍脑一想
我靠
应该把小明和小红拉过来
让他们一起帮我摸鱼啊
也就是让小明和小红同时一人摸 10 条鱼
想想就开心
在 小编 的威逼利诱下
他们俩不情愿的手拉着手来到了河边
小编看小红是女生
就让小红每摸一条鱼休息 2 秒钟
而小明每摸一条鱼休息 1 秒钟
先扔一段代码给你
在这里呢
我们创建了一个线程类
然后继承 threading.Thread
在我们这个线程类里面定义了一个 run 方法
这个 run 方法去调用了摸鱼的方法
可以看到我们创建了两个线程
一个叫小明线程
一个叫小红线程
thread1= MyThread(1,"小明",1)thread2= MyThread(2,"小红",2)
当我们的线程调用 start 方法的时候
它们就会去执行 run 方法
而我们用到的 join 方法呢
是为了让线程执行完
再终止主程序
运行一下就是这样
开始线程:小明开始线程:小红小明 开始摸鱼2019-03-1023:15:26小红 开始摸鱼2019-03-1023:15:27小明 开始摸鱼2019-03-1023:15:27小明 开始摸鱼2019-03-1023:15:28小红 开始摸鱼2019-03-1023:15:29小明 开始摸鱼2019-03-1023:15:29小明 开始摸鱼2019-03-1023:15:30小明 开始摸鱼2019-03-1023:15:31小红 开始摸鱼2019-03-1023:15:31小明 开始摸鱼2019-03-1023:15:32小明 开始摸鱼2019-03-1023:15:33小红 开始摸鱼2019-03-1023:15:33小明 开始摸鱼2019-03-1023:15:34小红 开始摸鱼2019-03-1023:15:35小明 开始摸鱼2019-03-1023:15:35退出线程:小明小红 开始摸鱼2019-03-1023:15:37小红 开始摸鱼2019-03-1023:15:39小红 开始摸鱼2019-03-1023:15:41小红 开始摸鱼2019-03-1023:15:43小红 开始摸鱼2019-03-1023:15:45退出线程:小红退出主线程Processfinishedwithexitcode0
恩
小编再也不用摸鱼了
后来小明和小红都不乐意了
凭什么就我们两个摸鱼
这时候 小编 只能去找更多人了
连 小编 家的狗都叫过来了
然后
就疯狂的开启线程
thread1= MyThread(1,"小明",1)thread2 = MyThread(2,"小红",2)thread3 = MyThread(3,"小黄",2)thread4 = MyThread(4,"小绿",2)...thread5 = MyThread(55,"小青",2)thread6 = MyThread(56,"小白",2)thread7 = MyThread(57,"小狗",2)
这可不行
因为频繁的创建线程 销毁线程
非常的浪费资源
所以呢
应该把他们放到池子里面去
哈,也就是
线程池
通过线程池就可以重复利用线程
不会造成过多的浪费
在 python 中
可以使用 ThreadPoolExecutor 来实现线程池
我们来往池子里塞 20 个线程
然后在循环的时候每次拿一个线程来摸鱼
运行一下
xiaobian开始摸鱼2019-03-1023:30:10xiaobian开始摸鱼2019-03-1023:30:11xiaobian开始摸鱼2019-03-1023:30:12xiaobian开始摸鱼2019-03-1023:30:13xiaobian开始摸鱼2019-03-1023:30:14xiaobian开始摸鱼2019-03-1023:30:15xiaobian开始摸鱼2019-03-1023:30:16xiaoshuaib3开始摸鱼2019-03-1023:30:17xiaoshuaib3开始摸鱼2019-03-1023:30:18xiaoshuaib4开始摸鱼2019-03-1023:30:19xiaoshuaib4开始摸鱼2019-03-1023:30:20xiaoshuaib4开始摸鱼2019-03-1023:30:21
可以看到
我们每次从线程池里面去拿一个线程来摸鱼
这样就不会去重复的创建销毁线程了
当然
我们还可以用一个叫做 Queue 的队列来创建线程池
队列嘛~
就是可以往里塞东西
也可以往里拉东西
所以我们在使用队列的时候
最常用的方法就是 put 和 get 了
还是拿摸鱼为例
我们创建一个长度为 6 的队列
接着根据队列的长度创建了线程
每个线程都让它们处于守护状态
也就是需要的时候
马上执行
defqueue_pool(): queue = Queue(6) foriinrange(queue.maxsize): t = CustomThread(queue) t.setDaemon(True) t.start()
接着我们就可以用 put 方法
把我们想做的事情往队列里面塞
比如这里我们想要摸鱼
fori inrange(20): queue.put(moyu)queue.join()
defmoyu(): print(" 开始摸鱼 %s"% (time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())))
要执行的话就需要去队列里面取了
q_method =self.__queue.get()q_method()self.__queue.task_done()
完整代码如下
本篇就到这里吧!
下一篇我们讲讲如何用多线程爬取万恶的妹子图!