python多线程和线程池

在python中,常用的多线程的模块有这么几个

  • _thread
  • threading
  • Queue

之前有个 thread 模块,被 python3 抛弃了,改名为 _thread。

但其实 _thread 也没什么人用,因为 _thread 有的 threading 都有,_thread 没有的 threading 依然有。

那么接下来我们就来尝试 threading 吧

示例

每天得摸 20 条鱼,每隔一秒钟摸一条,也就是这样

import time

def moyu_time(name, delay, counter):
 while counter:
   time.sleep(delay)
   print("%s 开始摸鱼 %s" % (name, time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())))
   counter -= 1


if __name__ == '__main__':
 moyu_time('rogn',1,20)

但是,现在我们知道了多线程,就可以找人帮忙一起摸鱼,

import time
import threading

# 创建一个线程子类
class MyThread(threading.Thread):
    def __init__(self,threadID, name, counter):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.counter = counter

    def run(self):
        print("开始线程:" + self.name)
        moyu_time(self.name, self.counter, 10)
        print("退出线程:" + self.name)


def moyu_time(name, delay, counter):
    while counter:
        time.sleep(delay)        
        print("%s 开始摸鱼 %s" % (name, time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())))
        counter -= 1


if __name__ == '__main__':
    # 创建新线程
    # 让小明摸一次鱼休息1秒钟
    # 让小红摸一次鱼休息2秒钟
    thread1 = MyThread(1, "小明", 1)
    thread2 = MyThread(2, "小红", 2)
    # 开启新线程
    thread1.start()
    thread2.start()
    # 等待至线程中止
    thread1.join()
    thread2.join()
    print ("退出主线程")

在这里,我们创建了一个线程类,它继承了 threading.Thread。在我们这个线程类里面定义了一个 run 方法,这个 run 方法去调用了摸鱼的方法。

可以看到我们创建了两个线程,一个叫小明线程,一个叫小红线程,当我们的线程调用 start 方法的时候它们就会去执行 run 方法。

因为频繁的创建线程 销毁线程,非常的浪费资源,所以我们创建线程池,通过线程池就可以重复利用线程。

在 python 中,可以使用 ThreadPoolExecutor 来实现线程池,

import time
from concurrent.futures import ThreadPoolExecutor


def moyu_time(name, delay, counter):
    while counter:
        time.sleep(delay)        
        print("%s 开始摸鱼 %s" % (name, time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())))
        counter -= 1


if __name__ == '__main__':
    pool = ThreadPoolExecutor(10)
    for i in range(1,5):
        pool.submit(moyu_time('rogn'+str(i),1,3))

我们还可以用一个叫做 Queue 的队列来创建线程池,最常用的方法就是 put 和 get 了。

我们创建一个长度为 6 的队列,接着根据队列的长度创建了线程,每个线程都让它们处于守护状态,也就是需要的时候能马上执行:

def queue_pool():
  queue = Queue(6)
  for i in range(queue.maxsize):
    t = CustomThread(queue)
    t.setDaemon(True)
    t.start()

接着我们就可以用 put 方法,把我们想做的事情往队列里面塞,比如这里我们想要摸鱼:

for i in range(20):
  queue.put(moyu)
queue.join()

完整代码如下:

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()

 

 

参考链接:https://zhuanlan.zhihu.com/p/58925023

posted @ 2020-01-17 10:32  Rogn  阅读(945)  评论(0编辑  收藏  举报