繁体   English   中英

多处理python:循环运行额外时间

[英]Multi Processing python: Loop running extra times

我正在尝试使用多处理附加到 csv 文件。 我有多个要循环的 csv 文件。 此函数适用于普通的 for 循环,但不适用于多处理。 希望有人可以对此有所了解。

我的功能代码如下:

 def read_write2(j, lock):
    #i = 2
    with open('C:\\Users\\user\\Documents\\filereader\\FileFolder\\sample_new{}.csv'.format(j), "r") as a_file: #input file
        #i = i + 1
        with open('samples2.csv','a') as file: #output file
            for line in a_file:
                lock.acquire()
                stripped_line = line.strip()
                a = len(stripped_line)
                if "©" in stripped_line or "flow" in stripped_line or a>254:
                    pass
                else:
                    file.write(stripped_line)
                    file.write("\n")
                lock.release()

我这里的多处理代码如下:

if __name__ == "__main__":
    lock = Lock()
    processes = []

    for i in range(2,fileno+1):
        print(i)
        process = Process(target=read_write2, args=(i,lock)) #creating a new process
        processes.append(process) #appending process to a processes list

    for process in processes:
        print(process)
        process.start()

    for process in processes: #loop over list to join process
        process.join() #process will finish before moving on with the script

输出如下:

7
2
3
4
5
6
7
<Process name='Process-1' parent=24328 initial>
<Process name='Process-2' parent=24328 initial>
<Process name='Process-3' parent=24328 initial>
<Process name='Process-4' parent=24328 initial>
<Process name='Process-5' parent=24328 initial>
<Process name='Process-6' parent=24328 initial>
7
7
7
7
7
7

谢谢你。

是的。 不去上班。 您的每个线程在文件中都有一个不同的“句柄”,因为您已经多次打开它。 您将需要打开它一次,然后将其传递给线程。

如前所述,您多次打开和写入同一个文件,并且没有文件锁定或同步会导致麻烦。 这可能是由于文件中的位置在进程之间没有更新,因此一个进程不知道另一个进程写入文件,并从与其他进程相同的位置开始写入文件。 有更好的方法可以做到这一点,但尝试对代码进行最小的调整,我建议使用锁来打开、写入和关闭输出文件,因此顺序如下所示:

with open('C:\\Users\\user\\Documents\\filereader\\FileFolder\\sample_new{}.csv'.format(j), "r") as a_file: #input file
    for line in a_file:
        if ...:
            ...
        else:
            lock.acquire()
            with open('samples2.csv','a') as file: #output file
                ...
            lock.release()

尽管这会导致磁盘 I/O 的开销很大,但这应该是对代码的最小更改,以使其使用多处理工作。 整个功能将是:

def read_write2(j, lock):
    with open('C:\\Users\\user\\Documents\\filereader\\FileFolder\\sample_new{}.csv'.format(j), "r") as a_file: #input file
        for line in a_file:
            stripped_line = line.strip()
            a = len(stripped_line)
            if "©" in stripped_line or "flow" in stripped_line or a>254:
                pass
            else:
                lock.acquire()
                with open('samples2.csv','a') as file: #output file
                    file.write(stripped_line)
                    file.write("\n")
                lock.release()

PS 根据文件的数量、文件的大小、输出的行数等很多因素,每个进程写入自己的文件,然后将输出整理到一个文件中,可能会更有效率。主循环。 这节省了大量的文件打开/关闭,并消除了对锁的需要。 例如,将函数改写如下:

def read_write2(j):
    with open('C:\\Users\\user\\Documents\\filereader\\FileFolder\\sample_new{}.csv'.format(j), "r") as a_file: #input file
        with open('samples2_{}.csv'.format(j),'a') as file: #output file
            for line in a_file:
                stripped_line = line.strip()
                a = len(stripped_line)
                if "©" in stripped_line or "flow" in stripped_line or a>254:
                    pass
                else:
                    file.write(stripped_line)
                    file.write("\n")

然后,在主代码中(在if __name__ == "__main__":下),替换以下代码:

for process in processes: #loop over list to join process
    process.join() #process will finish before moving on with the script

有了这个:

with open('samples2.csv', 'w') as out_f:
    for e, process in enumerate(processes):
        process.join()
        with open('samples2_{}.csv'.format(e+2), 'r') as in_f:
            out_f.write(in_f.read())    # NOTE: this is highly inefficient, and may consume too much memory. But that's not relevant to the question at hand.

谢谢大家的意见。 他们帮助我找到了答案。

答案实际上是把所有东西都放在 main 中。 它似乎工作正常,它已经解决了错误。 我正在检查 1000 和 1000 个网址。

我将所有函数声明放入 if name == " main " 并能够解决它。

再次感谢大家。 :)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM