Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.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_File_Background_Parallel Processing_Loading - Fatal编程技术网

python后台并行文件读写器

python后台并行文件读写器,python,file,background,parallel-processing,loading,Python,File,Background,Parallel Processing,Loading,我有一个我认为相当简单的问题,但我似乎不能像我希望的那样让它工作。我有大约200~200 MB的文件,足以让我无法一次将它们全部加载到内存中。每个文件都需要与另一个文件一起处理一次(处理功能的操作约为20000次)。我需要在文件中循环多次,例如: for i in xrange(len(file_list)-1): #go through each file if i==0: f = read(file_list[i]) #load in the first fil

我有一个我认为相当简单的问题,但我似乎不能像我希望的那样让它工作。我有大约200~200 MB的文件,足以让我无法一次将它们全部加载到内存中。每个文件都需要与另一个文件一起处理一次(处理功能的操作约为20000次)。我需要在文件中循环多次,例如:

for i in xrange(len(file_list)-1): #go through each file
    if i==0: 
        f = read(file_list[i])   #load in the first file
    else:
        f = g0  #we've already loaded in the next file once, don't re-load it
    for j in xrange(i+1,len(file_list)): #go through each other file to get all unique pairs
        g = read(file_list[i+j+1])  # takes 5 s
        answer.append(processing_function(f,g)) # takes 10s
        if j==0:
           g = g0 # this will be "f" for the next iteration of the outer loop
外部循环只需要加载文件1,然后它可以从内部循环的第一次迭代中获取已加载的文件作为其下一个值。内部循环需要加载(len(file_list)-i)文件并处理它们。因为我无法在内存中保存约200个文件,并且没有简单的方法来分解文件列表(因为每个文件需要彼此配对一次)

是否有一种明显的方法可以并行化read()函数,使其至少读取下一个文件,即在执行processing_函数(f_i,g_j)期间读取g_j+1?我尝试过线程化和多处理,并且我能够将读取的数据卸载到不同的线程/进程中,但它从来没有并行运行过(例如,处理函数()的执行在我得到一个g时立即开始,而未来的g_j则在后台加载)。我要么设法挂起程序(使用多处理),要么在处理第一个函数(使用线程)之前将一堆文件加载到队列中

我希望这是简单的执行,我只是搞砸了一个细节

这就是我到目前为止所尝试的(来自其他地方有人建议的代码)——看起来这应该满足我的要求,但正如我所说的,似乎QueuedFileReader()中的file_worker方法在将控制权返回给QueuedFileReader是其生成器的循环之前,会将大小为_的文件放入队列中。如果file_worker能够独立运行,并且当队列中的单个文件准备好进行下一次()调用时,使用QueuedFileReader()的循环就可以继续进行,这将是完美的

这被称为:

for j,fnm,g in QueuedFileReader(flz[i+1:],tmp_dir,QUEUE_SIZE):
    #the code that runs on object "f" from the outer loop and "g" that should be supplied off the top of the queue on each next() call to QueuedFileReader()

一个完整的黑客,但在类似的情况下,我所做的是
os.system(“cp bigfile/dev/zero&”)
。。。这将在后台运行,并将整个文件预加载到缓存中。另一个注意事项是,您最终会在解决方案中读取约20000个文件。如果加载是并行进行的并且所需时间少于处理时间,这可能无关紧要,但是如果加载了,那么就有可能改进:例如,如果内存可以容纳20个文件而不是2个,那么您可以在f[0]…f[9]中加载10个文件,在g[0]…g[9]中加载10个文件,并对它们进行所有交叉计算。这将文件读取次数减少到~2000次(当然,您需要小心才能正确处理)。多处理的问题是,您必须在子进程和父进程之间共享200MB的读入数据。如果您通过共享内存或mmap来实现这一点,那么它与首先对文件进行mmap完全相同;如果您通过管道/队列/其他方式进行操作,则可能会增加比节省更多的开销。因此,您可以获得的唯一好处是预缓存的意外好处(正如Armin Rigo所建议的,您可以获得更简单的好处)。并行化的更好方法可能是将输入分解为多组文件对,并并行运行这些组。因此,首先,进程0比较文件0和文件1、2、…、100,而进程1比较文件100和文件101、…、200。当然,进程0最终必须读取文件101才能与文件0进行比较,但它们在大多数情况下可以彼此远离。如果进程的数量正确,通常应该有一个或多个进程在工作,而其他进程在I/O上被阻塞。但是,按照
线程化
所述的方法,这样做应该相对容易。如果你给我们看你的代码,应该可以找出你做错了什么。但请记住,对于Python 3.2之前的版本,拥有一个CPU绑定线程实际上会破坏I/O绑定线程的性能,因此可能不值得这么做。你必须测试才能发现。(您可以通过将I/O和预处理移动到无GIL的C中来解决这个问题,例如,使用
numpy
pandas
而不是纯Python,或者编写自己的Cython代码……)
for j,fnm,g in QueuedFileReader(flz[i+1:],tmp_dir,QUEUE_SIZE):
    #the code that runs on object "f" from the outer loop and "g" that should be supplied off the top of the queue on each next() call to QueuedFileReader()