Python每天学一点之Threading和queue
自定义类继承 Thread
之前学习过Threading,在爬虫上也用上了。不过还可以通过继承Thread来实现多线程可以提高对线程任务的个性化定制。这里也学习一下
学习链接:
https://docs.python.org/zh-cn/3/library/threading.html
https://blog.csdn.net/briblue/article/details/85101144
https://www.cnblogs.com/franknihao/p/6627857.html
https://www.bbsmax.com/A/MyJxZ0Kpdn/
run方法
代表线程活动的方法。
你可以在子类型里重载这个方法。 标准的
run()
方法会对作为 target 参数传递给该对象构造器的可调用对象(如果存在)发起调用,并附带从 args 和 kwargs 参数分别获取的位置和关键字参数
demo:
import threading class MyThread(threading.Thread): def __init__(self,id): threading.Thread.__init__(self) #super(Son, self).__init__() self.id=id def run(self): print('good'+self.id) if __name__=="__main__": threading_list=[] thread_count=4 for i in range(thread_count): threading_list.append(MyThread(str(i))) for i in threading_list: i.start() for i in threading_list: i.join()
queue
学习链接:
https://docs.python.org/zh-cn/3/library/queue.html?highlight=queue#module-queue
https://www.cnblogs.com/franknihao/p/6627857.html
queue
模块实现了多生产者、多消费者队列。这特别适用于消息必须安全地在多线程间交换的线程编程。模块中的Queue
类实现了所有所需的锁定语义。模块实现了三种类型的队列,它们的区别仅仅是条目取回的顺序。在 FIFO 队列中,先添加的任务先取回。在 LIFO 队列中,最近被添加的条目先取回(操作类似一个堆栈)。优先级队列中,条目将保持排序( 使用
heapq
模块 ) 并且最小值的条目第一个返回。在内部,这三个类型的队列使用锁来临时阻塞竞争线程;然而,它们并未被设计用于线程的重入性处理
queue模块中的常用方法:
- queue.qsize() 返回队列的大小
- queue.empty() 如果队列为空,返回True,反之False
- queue.full() 如果队列满了,返回True,反之False
- queue.full 与 maxsize 大小对应
- queue.get([block[, timeout]])获取队列,timeout等待时间
- queue.get_nowait() 相当queue.get(False)
- queue.put(item) 写入队列,timeout等待时间
- queue.put_nowait(item) 相当queue.put(item, False)
- queue.task_done() 在完成一项工作之后,queue.task_done()函数向任务已经完成的队列发送一个信号
- queue.join() 实际上意味着等到队列为空,再执行别的操作
demo:
from queue import Queue queue=Queue() with open('dict.txt','r')as f: for i in f: queue.put('http://127.0.0.1'+i.rstrip('\n')) for i in range(3): print(queue.get()) queue.task_done()
两者结合
import threading from queue import Queue class MyThread(threading.Thread): def __init__(self,queue): threading.Thread.__init__(self) self.queue=queue def run(self): i=self.queue.get() print('hello {}'.format(i)) if __name__=="__main__": queue=Queue() threading_list=[] thread_count=4 for i in 'yunying': queue.put(i) for i in 'yunying': threading_list.append(MyThread(queue)) for i in threading_list: i.start() for i in threading_list: i.join()
但是我们有时候不能给太多的线程,只能给到几个线程的时候,可以这样:
import threading import time from queue import Queue class MyThread(threading.Thread): def __init__(self,queue): threading.Thread.__init__(self) self.queue=queue def run(self): while not self.queue.empty(): i=self.queue.get() print(threading.current_thread().name+' hello {}'.format(i)) print('还有'+str(self.queue.qsize())+'个') if __name__=="__main__": queue=Queue() threading_list=[] thread_count=2 for i in 'yunying': queue.put(i) for i in range(3): threading_list.append(MyThread(queue)) for i in threading_list: i.start() for i in threading_list: i.join()
输出:
Thread-1 hello y 还有6个 Thread-1 hello u 还有5个 Thread-1 hello n 还有4个 Thread-1 hello y 还有3个 Thread-1 hello i 还有2个 Thread-1 hello nThread-2 hello g 还有0个 还有0个