定时器对象

此类表示一个操作应该在等待一定的时间之后运行 --- 相当于一个定时器。 Timer 类是 Thread 类的子类,因此可以像一个自定义线程一样工作。与线程一样,通过调用 start() 方法启动定时器。而 cancel() 方法可以停止计时器(在计时结束前), 定时器在执行其操作之前等待的时间间隔可能与用户指定的时间间隔不完全相同。

下面举个例子:

import threading
def run():
    print("定时器启动了!")
    timer= threading.Timer(5,run)#调用自身函数,相当于自己循环
    print(threading.current_thread())#查看线程数是不是主函数启动的线程
    timer.start()

if __name__ == '__main__':
    t1 = threading.Timer(5,function=run)#不是target=run
    t1.start()

运用类创建定时器时,相关参数如下:

class threading.Timer(interval, function, args=None, kwargs=None)

创建一个定时器,在经过 interval 秒的间隔事件后,将会用参数 args 和关键字参数 kwargs 调用 function。如果 args 为 None (默认值),则会使用一个空列表。如果 kwargs 为 None (默认值),则会使用一个空字典。

cancel() 停止定时器并取消执行计时器将要执行的操作。仅当计时器仍处于等待状态时有效。

队列

Python的Queue模块中提供了同步的、线程安全的队列类,包括FIFO(先入先出)队列Queue,LIFO(后入先出)队列LifoQueue,和优先级队列PriorityQueue。这些队列都实现了锁原语,能够在多线程中直接使用。可以使用队列来实现线程间的同步。

下面是一些相关参数的说明:

queue.Queue()先入先出
queue.LifoQueue()后入先出
queue.PriorityQueue()可设置优先级
上面三个可传入参数maxsize设置可存储数据的数量


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() 实际上意味着等到队列为空,再执行别的操作

举个例子:

import queue
import time
"""队列之生产者消费者模型"""
q = queue.Queue(maxsize=10)

def put_in():#生产者
    count =1
    while True:
        q.put(f'产品{count}')
        print(f'生产了产品{count}')
        count +=1
        time.sleep(2)

def get_out(name):
    while 1:
        print(f'{name}买走了产品{q.get()}')

if __name__ == '__main__':
    p = threading.Thread(target=put_in)
    p.start()
    g = threading.Thread(target=get_out,args=('小明',))#传入元组
    g.start()

上述的生产者和消费者模型,读者自行理解。

线程池

线程池可以提高性能,防止启动大量线程而导致系统变慢,可以更简单的创建线程,
适用于突发的需要大量线程,而线程存在时间短的场景。线程池由concurrent.futures下的ThreadPoolExecutor提供,

下面讲解一些参数:

submit(fn,*args,**kwargs)将函数fn提交给线程池,后面是参数
map(fn,*iterables,timeout=None,chunksize=1)启动多线程,让函数fn分别使用后面的可迭代参数
shutdown(wait=True)关闭线程池

使用submit()函数提交后会返回一个Future对象
cancel()可以取消该线程,如果线程正在年行,不可取消,返回False,否则取消线程,并返回Truecancelled()返回线程是否被取消
running()返回线程是否正在运行
done()返回线程是否完成,包括取消和正常完成
result(timeout=None)获取该线程的返回结果,会阻塞线程,timeout是阻塞时间
add_done_callback(fn)线程结束后执行fn函数

来个例子:

import time
from concurrent.futures import ThreadPoolExecutor
def run(x):
    print(f'线程{x}')
    time.sleep(2)
    return x*10


if __name__ == '__main__':

    pool = ThreadPoolExecutor(max_workers=2)
    future1 = pool.submit(run,1)
    future2 = pool.submit(run,2)
    future3 = pool.submit(run,3)
    #查看线程1是否完成
    print(future1.done())
    time.sleep(3)
    #查看线程2是否完成
    print(future2.done())
    #获取线程1的返回值
    print(future1.result())
    print('程序结束')

上述程序能够清楚地反应线程的运作情况,读者自行运行,查看结果。