多处理问题

时间:2012-06-14 20:42:00

标签: python python-2.7

所以我只是尝试多处理并阅读文本doc中的每一行。有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() 

2 个答案:

答案 0 :(得分:7)

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

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

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

进程1调用readline,它将文件0-4095从文件读入其缓冲区,然后扫描该缓冲区以获取50行字节的换行符,并返回前50个字节。到目前为止,非常好。

进程2调用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只是它的一个副本,但你不想依赖它。)

答案 1 :(得分:1)

所以,我改变它使用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