使用多进程并行处理stdin行

时间:2018-09-27 11:17:40

标签: python multiprocessing

我有一个基本脚本,该脚本逐行读取一个csv文件,对每一行进行一些基本处理,并使用此脚本确定是否要保留该行。如果保留,则将其放入缓冲区数组,然后再写入缓冲区数组(如果文件无法放入RAM,则适当地分块处理,稍后再讨论)。我被告知,由于HDD的魔力,我将从写缓冲区中受益匪浅,而不仅仅是直接循环遍历每一行。

我试图查看是否可以通过与读取行的标准输入不同的过程来处理行,从而加快速度。显然,该脚本受I / O速度限制,因此我希望该脚本能够尽可能多地运行,而不是在等待CPU。

要尝试此操作,我使用管道将线从一条移动到另一条来设置2个进程。这似乎行得通,但是比我在馈送的线路上的单个循环中完成所有操作时要慢一个数量级。

基本工具摘录

outStream = open("updated.csv",'w')
outputBuffer = []
for line in sys.stdin:  
    row = line.strip()
    index = parseRow(row) # CPU-bound process

    if index not in mainList:
        outputBuffer.append(row)

    # some test to see if memory is filling up, if so dump it and reset buffer, just here to show logic atm
    if(getMem()>60):
        writeBuffer(outputBuffer, outStream)
        outputBuffer = []

# make sure last batch is written out
if outputBuffer != []:
    writeBuffer(outputBuffer, outStream)
outStream.close() 

尝试并行解决方案

def reader( lineConn, fileno ):
    for line in os.fdopen(fileno):
        lineConn.send(line)
    lineConn.send("end")

def parser( lineConn ):
    outputBuffer = []
    outStream = open("updated.csv",'w')
    while 1:
        line = lineConn.recv()
        if(line == "end"):
            break
        row = line.strip()
        index = parseRow(row)

        if index not in mainList:
            outputBuffer.append(row)

    writeBuffer(outputBuffer, outStream)

############ main
outputBuffer = []

lineRead, lineParse = Pipe()

io = sys.stdin.fileno() 
p1 = Process(target=reader, args=(lineRead,io))
p2 = Process(target=parser, args=(lineParse,)) 

p1.start()
p2.start()
p1.join()
p2.join()

我怀疑这与发送速度慢于接收速度有关,但我还在解析端设置了一个等待计时器(即,如果poll()为false,则请稍等片刻),但即使如此当我添加send(line)内容时,它会停顿下来,大概是因为我对这一切的工作方式还不够了解。

我有宏伟的计划来确保在需要完成写入时暂停读取,即文件不适合放入RAM,但在此之前被卡住了。

顺便说一句,解析低的部分原因是因为我需要搜寻csv(仅2 col)的逗号部分来挖掘索引,这意味着读取行以获取行,然后再次阅读以找到逗号并在其之前获取整数-是否有办法以某种方式让stdin处理这些问题?即读取该行并返回找到的第一个逗号的位置?

重要修改 实际上只是意识到任务需要将输出发送到stdout而不是直接写入文件,所以这意味着我不需要缓冲,因为HDD i / o仅在一端吗?

0 个答案:

没有答案