【问题标题】:Is a Python Queue needed for simple byte stream between threads?线程之间的简单字节流是否需要 Python 队列?
【发布时间】:2009-10-28 21:06:18
【问题描述】:
我有一个简单的线程,它从蓝牙 RFCOMM(类似串行端口)套接字中获取字节并将它们转储到 Queue.Queue(FIFO)中,这似乎是线程之间交换数据的典型方法。工作正常。
这是不是有点矫枉过正?我可以只使用一个字节数组然后让我的阅读器线程.append(somebyte) 和处理函数只是.pop(0)?我不确定 Queue 中的保护是否适用于更复杂的“多生产者、多消费者队列”以及点对点字节流的浪费。与更简单的数据类型相比,使用 Queue 执行诸如刷新队列或抓取多个字节之类的操作似乎更尴尬。
我猜答案可能与.pop() 是否是原子的有关,但那会不会很重要?...
【问题讨论】:
标签:
python
multithreading
queue
【解决方案1】:
使用Queue,您保证在任何 Python 实现和版本中都是线程安全的。依赖某个其他对象的这种或那种方法是“原子的”(在给定的实现和版本中)通常会让您受制于这种“原子性”而不是强有力的保证(只是特定点发布的实现工件&c你'正在使用),因此在任何升级或移植到其他 Python 实现时都会引入微妙的、非常难以调试的竞争条件。
如果您的分析告诉您Queue 的强大和一般保证正在成为您特定生产者-消费者用例的瓶颈,请创建您自己的更简单的保证线程安全 FIFO 队列/流。例如,如果您发现(不考虑竞争条件)append 和 pop 非常适合您使用,只需创建一个使用锁获取/释放来保护它们的类(使用 with 语句) -- Queue 增加了微不足道的开销来支持多个生产者和消费者,您可以将这几纳秒的时间缩短!-)
【解决方案2】:
是的,pop() 是原子的,但如果性能不是非常重要,我会坚持使用 Queue。
【解决方案3】:
如果输入的速度足够快,您总是可以在将字节推入队列之前将字节缓冲到一个字符串中。这可能会通过减少完成的锁定量来增加吞吐量,但会在接收端增加一点延迟。