当前位置: 代码迷 >> 综合 >> python 线程(2)-- 线程通信event,queue
  详细解决方案

python 线程(2)-- 线程通信event,queue

热度:3   发布时间:2023-11-21 17:47:28.0

一.Event

如果程序中的其他线程需要通过判断某个线程的状态来确定自己下一步的操作,这时候就可以用threading为我们提供的Event对象,Event对象主要有一下几个方法:

  isSet():返回event的状态值;

  wait():如果 event==False 将阻塞当前线程;

  set(): 设置event的状态值为True,所有阻塞池的线程激活进入就绪状态, 等待操作系统调度;

  clear():恢复event的状态值为False。

  有如下需求:获取当前时间的秒数的个位数,如果小于5,设置子线程阻塞,如果大于5则设置子进程非阻塞。代码如下:

from threading import Event, Threadimport timefrom datetime import datetimedef func(e):print('子线程:开始运行……')while True:print('子线程:现在事件秒数是{}'.format(datetime.now().second))e.wait()  # 阻塞等待信号  这里插入了一个Flag  默认为 Falsetime.sleep(1)e = Event()p = Thread(target=func, args=(e,))p.daemon=Truep.start()for i in range(10):s = int(str(datetime.now().second)[-1])#获取当前秒数的个位数if s < 5:print('子线程线入阻塞状态')e.clear()  # 使插入的flag为False 线程线入阻塞状态else:print('子线程取消阻塞状态')e.set()  # 线程线入非阻塞状态time.sleep(1)e.set()print("主线程运行结束……")
>>>输出结果:子线程:开始运行……子线程:现在事件秒数是43子线程线入阻塞状态子线程线入阻塞状态子线程取消阻塞状态子线程取消阻塞状态子线程:现在事件秒数是46子线程取消阻塞状态子线程:现在事件秒数是47子线程取消阻塞状态子线程:现在事件秒数是48子线程取消阻塞状态子线程:现在事件秒数是49子线程线入阻塞状态子线程:现在事件秒数是50子线程线入阻塞状态子线程线入阻塞状态主线程运行结束……

二.queue (推荐使用)

python中Queue模块提供了队列都实现了锁原语,是线程安全的,能够在多线程中直接使用。Queue中的队列包括以下三种:

  1)FIFO(先进先出)队列, 第一加入队列的任务, 被第一个取出;

  2)LIFO(后进先出)队列,最后加入队列的任务, 被第一个取出;

  3)PriorityQueue(优先级)队列, 保持队列数据有序, 最小值被先取出。

  Queue模块中的常用方法如下:

  qsize() 返回队列的规模

  empty() 如果队列为空,返回True,否则False

  full() 如果队列满了,返回True,否则False

  get([block[, timeout]])获取队列,timeout等待时间

  get_nowait() 相当get(False)

  put(item) 写入队列,timeout等待时间,如果队列已满再调用该方法会阻塞线程

  put_nowait(item) 相当put(item, False)

  task_done() 在完成一项工作之后,task_done()函数向任务已经完成的队列发送一个信号

  join() 实际上意味着等到队列为空,再执行别的操作。

import queueimport threadingdef fun():while True:try:data = q.get(block = True, timeout = 1) #不设置阻塞的话会一直去尝试获取资源except queue.Empty:print(' {}结束……'.format(threading.current_thread().name))breakprint(' {}取得数据:{}'.format(threading.current_thread().name , data))q.task_done()print(' {}结束……'.format(threading.current_thread().name))print("主线程开始运行……")q = queue.Queue(5)#往队列里面放5个数for i in range(5):q.put(i)for i in range(0, 3):t = threading.Thread(target=fun , name='线程'+str(i))t.start()q.join() #等待所有的队列资源都用完print("主线程结束运行……")》》》
输出结果:主线程开始运行……线程0取得数据:0线程0结束……线程0取得数据:1线程0结束……线程1取得数据:2线程0取得数据:3线程0结束……线程0取得数据:4线程0结束……线程1结束……主线程结束运行……线程1结束……线程2结束……线程0结束……

参考:

12.3 线程间通信 — python3-cookbook 3.0.0 文档

**python并发编程系列之多线程

  相关解决方案