【问题标题】:Using thread to read a file and passing data使用线程读取文件并传递数据
【发布时间】:2018-03-28 02:59:44
【问题描述】:

我正在研究 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.join() 的示例在这里需要吗?
  2. 当使用 while 循环打印队列时,它会这样打印:

    ['KeePass'] 如何在没有 [''] 的情况下打印它并获得纯字符串 KeePass?

【问题讨论】:

  • 1.不确定python线程库2。你不只是打印一个列表吗?请尝试使用 backup_list.get()[0]。无需过多介绍您的代码,备份列表是否应该包含超过 1 个元素?您是否要打印出其中的所有项目?为什么不直接做for item in backup_list: print(item)
  • @bhow - 但是如果列表中还有其他项目,我将不得不获取队列的长度,根据长度运行 for 循环并将其插入[]跨度>
  • @bhow - 因为 Queue 不能使用 for 循环进行迭代,所以我尝试了这个,它抛出了一个错误

标签: python multithreading python-3.x io


【解决方案1】:

线程的主要问题是确保没有东西会爆炸,或者如果有东西会爆炸,你已经涵盖了那个场景并且你愿意让它爆炸。考虑到这一点,并且没有可行的方法可以在不牺牲多线程优势的情况下使用当前操作系统架构自动化这部分线程,让我们了解您的选择和实现的正确性。

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() 处于阻塞状态并且没有超时,这不是错误,我只是指出这一点以确保这是有意识的决定,并且在扩展此示例的功能时必须考虑到这一点。

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()

【讨论】:

  • 你是如何学习多线程的?你用了什么资源?
猜你喜欢
  • 2019-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多