Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/276.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_Python 2.7 - Fatal编程技术网

Python 多处理问题

Python 多处理问题,python,python-2.7,Python,Python 2.7,所以我只是尝试多处理并读取文本文档中的每一行。共有660918行,据我所知,它们的长度都是一样的。虽然,在下面的代码中,行的长度似乎发生了变化,但我无法找出原因 import multiprocessing class Worker(multiprocessing.Process): def __init__(self,in_q): multiprocessing.Process.__init__(self) self.in_q = in_q d

所以我只是尝试多处理并读取文本文档中的每一行。共有660918行,据我所知,它们的长度都是一样的。虽然,在下面的代码中,行的长度似乎发生了变化,但我无法找出原因

import multiprocessing

class Worker(multiprocessing.Process):
    def __init__(self,in_q):
        multiprocessing.Process.__init__(self)
        self.in_q = in_q
    def run(self):      
        while True:
            try:
                in_q.get()
                temp_line = short_file.readline()
                temp_line = temp_line.strip().split()
                print len(temp_line)
                self.in_q.task_done()
            except:                              
                break     

if __name__ == "__main__":
    num_proc = 10
    lines = 100000 #660918 is how many lines there actually are
    in_q = multiprocessing.JoinableQueue()
    File = 'HGDP_FinalReport_Forward.txt'
    short_file = open(File)

    for i in range(lines):
        in_q.put(i)    

    for i in range(num_proc):
        worker = Worker(in_q)
        worker.start()
    in_q.join() 

您在主进程中打开一个文件,然后在子进程中读取该文件。你不能那样做

文件对象实际上是一个原始文件句柄和内存缓冲区。每个进程共享文件句柄,但每个进程都有自己的内存缓冲区

假设所有的行都是50字节,内存缓冲区是4096字节

进程1调用readline,readline将文件中的0-4095字节读入其缓冲区,然后扫描该缓冲区中的换行符,换行符长度为50字节,并返回前50个字节。到目前为止,一切顺利

进程2调用readline,readline将文件中的4096-8191字节读入其缓冲区,然后扫描该缓冲区以查找换行符。第一个是4100,即5字节,因此它返回前5个字节

等等

从理论上讲,您可以通过执行无缓冲I/O来解决这个问题,但实际上,为什么?为什么不直接读一下你的主要流程中的台词呢?除了避免这个问题之外,这还可能提高并行性I/O本身就是顺序的,因此所有这些进程的大部分时间都会被阻塞在I/O上,这意味着它们对您没有任何好处


作为旁注,在run循环的顶部附近,您正在执行in_q.get()而不是self.in_q.get()。(这正好起作用,因为in_q是一个永远不会消失的全局变量,self.in_q只是它的一个副本,但你不想依赖它。)

所以,我将它改为使用Pool,它似乎起作用了。下面的比较好吗

import multiprocessing as mp

File = 'HGDP_FinalReport_Forward.txt'
#short_file = open(File)
test = []

def pro(temp_line):
    temp_line = temp_line.strip().split()
    return len(temp_line)

if __name__ == "__main__":
    with open("HGDP_FinalReport_Forward.txt") as lines:
        pool = mp.Pool(processes = 10)
        t = pool.map(pro,lines.readlines())
    print t

为什么不读取主进程中的行,并使用
多处理.Pool
将它们分发给子进程?上述内容并不能真正回答我的问题,除非出于某种原因,Pool会使所有行读取相同的长度。@user1423020:这与问题无关,但建议在try子句中插入尽可能少的行;通过这种方式,您可以防止您的程序自动忽略
print
语句中的问题。此外,建议捕获特定的异常,而不是使用覆盖的
except
语句来捕获任何内容;这也可能隐藏您没有预料到的问题。@user1423020:另一个重要的注意事项:我不建议在方法中使用全局变量(特别是在主程序中定义时)。这里,
short\u文件
run()
方法中“静默”使用。这迫使用户阅读所有代码,以了解每个方法使用的是什么。首选方法是显式传递变量或使用(实例或类)属性。@user1423020:还要注意,类Unix平台使用
fork()
,因此您的子进程知道
short\u file
是什么,但在Windows中不应该是这种情况。哇,回答得很好。我希望我能不止一次地向上投票。这很有帮助,但我对如何组织代码感到有点困惑,以至于我读的是主要的行而不是孩子们的行。你可能不应该把这作为一个答案,但是…我不确定你到底应该如何添加它。不管怎么说,是的,我认为这样更好。首先,因为您在父进程中读取所有文件,所以它现在可以工作了。这还意味着您正在分发CPU绑定的工作,而不是I/O绑定的工作,并且在分布式工作中没有阻塞,这意味着更高的效率和并行性。而且使用会使它变得更短,更容易阅读,更难犯一些小错误(比如in_q而不是self.in_q)。