我有一个简单的线程,它从蓝牙RFCOMM(类似串口)套接字中抓取字节并将它们转储到Queue.Queue
(FIFO),这似乎是在线程之间交换数据的典型方法。工作正常。
这是否过度杀伤?我可以使用bytearray然后让我的读者线程.append(somebyte)
和处理函数.pop(0)
吗?我不确定Queue中的保护是否适用于更复杂的“多生产者,多用户队列”以及点对点字节流的浪费。使用队列与更简单的数据类型相比,像刷新队列或抓取多个字节这样的事情看起来更尴尬。
我想答案可能与if .pop()
是原子的有关,但它会不会重要呢?...
答案 0 :(得分:3)
使用Queue
,您保证在任何实现和版本的Python中都是线程安全的。依赖于某种其他对象的“原子”(在给定的实现和版本中)的这种或那种方法,通常会让你受到这种“原子性”的支配,而不是强有力的保证(只是特定点释放的实现工件和放大器)。 c你正在使用)因此,对于其他Python实现的任何升级或端口都会引入微妙的,非常难以调试的竞争条件。
如果您的分析告诉您Queue
的强大且一般的保证是您的特定生产者 - 消费者用例的瓶颈,那么请创建您自己更简单的保证线程安全的FIFO队列/流。例如,如果您已经发现(根据竞争条件)append
和pop
将非常适合您的使用,那么只需创建一个通过锁获取/释放来保护每个人的类(使用with
语句) - Queue
增加了微不足道的开销来支持多个生产者和消费者,你可以减少这几纳秒的时间! - )
答案 1 :(得分:0)
是的,pop()是原子的,但如果性能不是非常重要,我会坚持使用Queue。
答案 2 :(得分:0)
如果输入速度足够快,您可以在将字节推送到队列之前将字节缓冲到字符串中。这可能会通过减少锁定量来增加吞吐量,但代价是接收端会有一点额外的延迟。