线程消息队列没有正确填充消息

时间:2018-02-07 19:13:39

标签: python multithreading

我有一个读取文件的函数,用一些数据对它们进行分组,然后将它们放在一个消息队列中,由一个线程通过套接字发送:

for filename in os.listdir(os.getcwd()):
    ... read in files and sort numerically ...
roke_data = {"filename" : None, "byte_string" : None}
for filename in lst:
    with open(filename, "r") as f:
        roke_data["filename"] = filename
        roke_data["byte_string"] = f.read()
        fileQueue.put(roke_data)
    fileQueue.join()
    exit()

我的线程的运行功能:

def run(self):
    try:
        self.connect_socket() #connects to a socket on localhost
        roke_data = self.fileQueue.get_nowait()
        print "Sending file: ", roke_data["filename"]
        self.sc.send(roke_data["byte_string"])
    except Queue.Empty:
        time.sleep(0.1)

我已经运行测试以确认fileQueue正在被填充,并且似乎正在填充正确数量的元素,但似乎只有少数元素实际上从队列中拉出来发送和更糟糕的是,一些文件正在队列中重复。例如,我正在读取的集合中的最后一个文件似乎被多次推送到队列中。我做错了什么?

1 个答案:

答案 0 :(得分:1)

首先,我会将每个文件的新dict对象放入队列,而不是一遍又一遍地重复使用相同的dict实例。此外,您需要发出信号,表示不再有项目被放入队列,例如通过None

for filename in lst:
    with open(filename, "r") as f:
        roke_data = dict(filename=filename, byte_string=f.read())
        self.fileQueue.put(roke_data)
self.fileQueue.join()
self.fileQueue.put(None)  # the kill pill

其次,我在你的消费者线程方法中看不到任何循环。你只是得到一个项目。你的代码片段丢失了吗?查看this example以了解如何从队列中消耗元素。

它分解为循环并阻止调用get()

def run(self):
    self.connect_socket() #connects to a socket on localhost
    while True:
        roke_data = self.fileQueue.get()  # blocking!
        if roke_data is None:
            break
        print("Sending file: ", roke_data["filename"])
        self.sc.send(roke_data["byte_string"])
        # Assuming it's a JoinableQueue
        self.fileQueue.task_done()