Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么python多线程和队列不能帮助加速读取大量文件?_Python_Multithreading_Queue - Fatal编程技术网

为什么python多线程和队列不能帮助加速读取大量文件?

为什么python多线程和队列不能帮助加速读取大量文件?,python,multithreading,queue,Python,Multithreading,Queue,我正在编写一个Python程序,从本地文件系统读取大约110000多个文本文件,并将它们推送到MongoDB中。这是我的代码片段 类EmailProducer(threading.Thread): 类EmailConsumer(threading.Thread): EmailProducer实例从本地文件系统读取文件,如果队列为空,则将其存储在队列中;EmailConsumer实例从队列中获取文件并将其推入Mongo。我还编写了相同功能的顺序版本。 我在我的Ubuntu12.0432位台式机上运

我正在编写一个Python程序,从本地文件系统读取大约110000多个文本文件,并将它们推送到MongoDB中。这是我的代码片段

类EmailProducer(threading.Thread):

类EmailConsumer(threading.Thread):

EmailProducer实例从本地文件系统读取文件,如果队列为空,则将其存储在队列中;EmailConsumer实例从队列中获取文件并将其推入Mongo。我还编写了相同功能的顺序版本。 我在我的Ubuntu12.0432位台式机上运行这两个程序,并使用I-5四核处理器对它们进行计时。多线程版本从1个生产者和7个消费者开始。然而,这两种方法都需要大约23.7秒的实时时间和21.7秒的用户时间。我原以为线程技术在这方面会有所帮助,但数字告诉我它没有帮助


有人对原因有什么见解吗

线程对于IO绑定的操作不是很有用。尤其是没有全局解释器锁。所以一次只能运行一个线程。我很惊讶没有线程它不会更快。查看使用或第三方库异步读取文件。

线程对于IO绑定的操作不是很有用。尤其是没有全局解释器锁。所以一次只能运行一个线程。我很惊讶没有线程它不会更快。请看使用或第三方库异步读取文件。

Python线程在某种程度上受到CPython中的限制,这可能会影响您的结果


所有C级扩展还需要在阻止外部资源时持有GIL。这意味着,如果您使用C层库(例如,与MongoDB对话),它可能会在操作时阻塞其他线程。(我不知道它是否会,只是它可能会。)

Python线程在某种程度上受到CPython中的限制,这可能会影响您的结果


所有C级扩展还需要在阻止外部资源时持有GIL。这意味着,如果您使用C层库(例如,与MongoDB对话),它可能会在操作时阻塞其他线程。(我不知道它是否会,只是可能会。)

单线程版本在我的测试中比线程版本好一点。单线程版本在我的测试中比线程版本好一点。可能限制来自硬盘驱动器。读取大量的小文件对硬盘来说是一项非常繁重的工作。可能限制来自硬盘。在硬盘上读取大量的小文件是非常费力的。
def __init__(self, threadID, queue, path):
    self.threadID = threadID
    self.queue = queue
    self.path = path
    threading.Thread.__init__(self)

def run(self):
    if (queue.empty()):
        files = os.listdir(self.path)
        print(len(files))
        for file in files:
            queue.put(file)
def __init__(self, threadID, queue, path, mongoConn):
    self.threadID = threadID
    self.queue = queue
    self.mongoConn = mongoConn
    self.path = path
    threading.Thread.__init__(self)
def run(self):
    while (True):
        if (queue.empty()):
            mongoConn.close()
            break
        file = queue.get()
        self.mongoConn.persist(self.path, file)