多线程 - 覆盖队列中的旧值?
multithreading - overwrite old value in queue?
我有两个线程:生产者和消费者。生产者定期获取信息并将其提供给消费者。消费者只需要最新的信息副本,并且会不定期地检查它,可能间隔很长时间。
似乎促进这种交流的最简单机制是创建一个 Queue.Queue(maxsize=1)
。但是,如果生产者在旧信息被消费之前获取了新信息,它将阻塞,直到消费者首先使用过时的信息。生产者有没有办法覆盖旧信息?
有没有更好的线程安全机制来实现这个?
最简单的解决方法可能是让生产者在放置之前消耗它的旧值(如果有的话)。您可以为此使用 Queue.get_nowait()
。
从风格上讲,我不太热衷于将队列用于仅用于保存一个对象的对象。一个普通的锁+一个引用变量将使代码的作用更加明显。
谢谢 Snild Dolkow。你的建议很有价值。在做进一步的研究时,我确实找到了一种似乎适合我的特殊情况的机制。 A collections.deque([iterable[, maxlen]])
将是线程安全的,在接受新数据时丢弃旧数据,并且根据 documentation:
They are also useful for tracking transactions and other pools of data
where only the most recent activity is of interest.
使用 maxlen=1
生产者将始终能够写入新数据。当消费者使用 pop()
时,它将始终获得最新数据。如果抛出一个IndexError
,表示双端队列为空,消费者会继续使用上次收到的数据。
我有两个线程:生产者和消费者。生产者定期获取信息并将其提供给消费者。消费者只需要最新的信息副本,并且会不定期地检查它,可能间隔很长时间。
似乎促进这种交流的最简单机制是创建一个 Queue.Queue(maxsize=1)
。但是,如果生产者在旧信息被消费之前获取了新信息,它将阻塞,直到消费者首先使用过时的信息。生产者有没有办法覆盖旧信息?
有没有更好的线程安全机制来实现这个?
最简单的解决方法可能是让生产者在放置之前消耗它的旧值(如果有的话)。您可以为此使用 Queue.get_nowait()
。
从风格上讲,我不太热衷于将队列用于仅用于保存一个对象的对象。一个普通的锁+一个引用变量将使代码的作用更加明显。
谢谢 Snild Dolkow。你的建议很有价值。在做进一步的研究时,我确实找到了一种似乎适合我的特殊情况的机制。 A collections.deque([iterable[, maxlen]])
将是线程安全的,在接受新数据时丢弃旧数据,并且根据 documentation:
They are also useful for tracking transactions and other pools of data where only the most recent activity is of interest.
使用 maxlen=1
生产者将始终能够写入新数据。当消费者使用 pop()
时,它将始终获得最新数据。如果抛出一个IndexError
,表示双端队列为空,消费者会继续使用上次收到的数据。