【问题标题】:Improper formatting while using threading and queues使用线程和队列时格式不正确
【发布时间】:2015-09-25 18:18:48
【问题描述】:

我在下面写的代码应该是这样输出的:

<Floor(Thread-3, started 44660)> <Bank(Thread-1, started 43356)> shutting down
<Floor(Thread-4, started 44108)> received a message: shutting down (0, 'UP')
<Bank(Thread-1, started 43356)> received a message: (1, 'DOWN')
<Bank(Thread-1, started 43356)> shutting down
<Bank(Thread-2, started 27800)> shutting down

但是,有时输出的格式似乎不一致。例如:

<Floor(Thread-3, started 27076)> <Bank(Thread-1, started 44608)>shutting down
<Floor(Thread-4, started 28772)>received a message:  (shutting down0, 'UP')

<Bank(Thread-1, started 44608)> received a message: (1, 'DOWN')
<Bank(Thread-1, started 44608)> shutting down
<Bank(Thread-2, started 41480)> shutting down

一致的数据在大多数程序中都很重要。为什么这个输出不一致,我该如何防止它?

import threading
import Queue

banks = []
floors = []

class Bank(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
        self.mailbox = Queue.Queue()
        banks.append(self.mailbox)

    def run(self):
        while True:
            data = self.mailbox.get()
            if data == 'shutdown':
                print self, 'shutting down'
                return
            print self, 'received a message:', data

    def stop(self):
        banks.remove(self.mailbox)
        self.mailbox.put('shutdown')
        self.join()

class Floor(threading.Thread):
    def __init__(self, number = 0):
        threading.Thread.__init__(self)
        self.mailbox = Queue.Queue()
        floors.append(self.mailbox)
        self.number = number

    def run(self):
        while True:
            data = self.mailbox.get()
            if data == 'shutdown':
                print self, 'shutting down'
                return
            print self, 'received a message:', data

    def stop(self):
        floors.remove(self.mailbox)
        self.mailbox.put('shutdown')
        self.join()

    def call(self, data):
        banks[0].put((self.number, data))

b0 = Bank()
b1 = Bank()
b0.start()
b1.start()
f0 = Floor(0)
f1 = Floor(1)
f0.start()
f1.start()
f0.call('UP')
f1.call('DOWN')
f0.stop()
f1.stop()
b0.stop()
b1.stop()

【问题讨论】:

  • 您所说的“不一致”是指额外的换行符,还是输出比这更交错?
  • @Andy 空格和换行符是可消耗的(但我想知道为什么它们也不一致)。最有趣的部分是(shutting down0, 'UP')。不知何故,这些消息每隔一段时间就会被连接起来。

标签: multithreading python-2.7 formatting queue


【解决方案1】:

最终,由于您的 call() 调用现在在不同的线程中执行,因此无法保证它们将同步执行(和输出)。如果你想保证输出不交错,你需要在你的打印调用周围放置一个大的全局锁(互斥锁)。

即使这样也不能保证它们的顺序一致 - 例如上面的不同线路可以很容易地切换 - 在这种情况下,您需要锁定链您的调用。顺便说一句,这首先会抵消多线程处理的几乎所有性能优势。

【讨论】:

  • 我认为 stdout 会被一个人声明,然后在另一个人完成之后。执行顺序无关紧要,但交错是有问题的。所以我的设计全错了?
  • print 不是线程安全的……但即使是,也只能解决行间的交错问题。线路本身仍然可以切换。所以是的,如果你想要同步输出,你需要一个同步的设计——线程是异步的野兽。
【解决方案2】:

print 不是线程安全的。但是,sys.stdout.write 是。

这确实解决了交错的直接问题,但我怀疑这是最合适的方法。

【讨论】:

    猜你喜欢
    • 2015-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多