使用线程读取文件并传递数据

时间:2017-10-16 14:36:15

标签: python multithreading python-3.x io

我正在研究Python和线程,更具体地说,是从线程中调用的方法返回数据。我的所有研究都引向了队列。但是,我不确定我是否真的正确地实现了它,我有一个问题。

import threading
import queue


def construct_list(read_file, backup):
    with open(read_file) as read_obj:
        backup.put(read_obj.readlines())
    backup.task_done()


backup_list = queue.Queue()
read_thread = threading.Thread(target=construct_list, args=("list.txt", backup_list,))


read_thread.start()
read_thread.join()

while backup_list.empty() is False:
    print(backup_list.get())

问题:

  1. 我是否正确实施并使用了Queue?我已经看到了代码调用queue.join()的示例,这是需要的吗?
  2. 使用while循环打印队列时,会按如下方式打印:

    [' KeePass的'] 如何在没有['']的情况下打印它,只需获得普通字符串KeePass?

1 个答案:

答案 0 :(得分:2)

线程的主要问题是确保没有任何东西会爆炸,或者如果某些东西爆炸,你就会覆盖那个场景并且你愿意让它爆炸。考虑到这一点,并且没有可行的方法来自动化当前操作系统架构的线程部分,而不牺牲多线程的好处,让我们进入您的选择和实现的正确性。

def construct_list(read_file, backup):
    with open(read_file) as read_obj:
        backup.put(read_obj.readlines())
    backup.task_done()

好吧,你好像倒退了。如果您阅读了某些内容,并且基于该内容将数据/命令/任何内容发布到队列以进行处理,则不会调用task_done(),因为您只请求完成任务。发布此类请求时,您不会执行该任务。

这里的第二个问题是将这些命令写入队列而没有超时。默认情况下queue.put()是阻塞的并且没有超时,这不是错误,我只是指出这一点以确保这是有意识的决定,并且在扩展此示例的功能时必须考虑它。 / p>

read_thread.start()
read_thread.join()

嗯......这实际上打败了多线程的整个想法。想法能够并行执行多个任务,在此处调用join(),您将阻止主线程直到工作线程完成。这基本上意味着您创建一个线程并执行所有操作的速度是单个线程的两倍。使用队列的整个想法是让多个线程在彼此通信的同时进行通信。您不应该以这种方式加入其他线程,只需在不再需要它并且已经处理队列之后再执行它。

while backup_list.empty() is False:
    print(backup_list.get())

首先,您不应该假设如果empty()返回False您的get()来电将不会阻止。如果主线程是GUI线程或需要连续运行的任何其他变体,您可能希望使用非阻塞调用来调用它,并通过跳过来处理非处理项。

其次,由于此队列用于通信,因此您需要发信号通知该任务已完成。您的任务是在传递给队列的元素上调用print()函数。在该元素上调用print后,您可以通过task_done()调用来表示该任务已完成。

最后,在这种情况下,不需要在队列上调用join()

@edit:至于第二个问题When printing the Queue using the while loop, it prints it like so: ['KeePass'] How can I print it without the [''] and just get the plain string KeePass? - 这与线程和队列无关。这是您使用readlines()读取文件内容并将结果转储到备份列表中的问题。我相信您正在研究连续阅读文件的示例,然后将这些结果拆分为单行或更恰当地使用read()