Python多处理映射\u async ready()和\u number\u未按预期工作

Python多处理映射\u async ready()和\u number\u未按预期工作,python,multiprocessing,Python,Multiprocessing,这有点复杂,我相信这是一个新手的错误,但我一辈子都不知道该去哪里找 正在尝试执行多处理映射\u async以处理大量文件。本质上,代码获取文件列表,在每个文件中查找MAC地址上的匹配项,如果匹配,则向另一个文件写出一行 nodb是我的图书馆……我还没有把所有的东西都包括进来(有点复杂)。我希望有人能指点我去哪里调试这个 问题是:该代码可以完美地处理60000个文件以下的任何文件。但是,当我将它指向一个包含595200个文件的目录时,检查它是否完成(使用_number_left)的小“while

这有点复杂,我相信这是一个新手的错误,但我一辈子都不知道该去哪里找

正在尝试执行多处理映射\u async以处理大量文件。本质上,代码获取文件列表,在每个文件中查找MAC地址上的匹配项,如果匹配,则向另一个文件写出一行

nodb是我的图书馆……我还没有把所有的东西都包括进来(有点复杂)。我希望有人能指点我去哪里调试这个

问题是:该代码可以完美地处理60000个文件以下的任何文件。但是,当我将它指向一个包含595200个文件的目录时,检查它是否完成(使用_number_left)的小“while true”循环停止工作…处理似乎在继续,但_number_left没有减少,ready()函数返回true…事实并非如此

每次运行62111或62112文件后,它就会停止。我添加了一个小的“dump”函数,以为我的队列已经满了

不知道还能告诉你什么…我错过了什么吗?(可能)请让我知道我还能告诉你什么来解决这个问题。我真的不知道什么是相关的

代码是:

import nodb_v09d as nodb

import netaddr
import sys
import collections
from multiprocessing import Pool, Queue
import itertools
import time

# Handle CLI arguments
#
nmultip = 1
args = sys.argv[1:]
nmultip = nodb.parseArgs(args)

# this function just gets the file list in the directory
todoPif = nodb.getFileList('/data/david/data/2012/05')

filterfields = { 10:set([int(netaddr.EUI('00-00-0a-0e-c9-be')),\
                         int(netaddr.EUI('00:15:ce:de:78:f3')),\
                         int(netaddr.EUI('3c-75-4a-ea-15-01')),\
                         int(netaddr.EUI('00-24-d1-1e-e9-be'))])
                 }
ff=collections.OrderedDict(sorted(filterfields.items()))

resultfields = [28,29,30,33]
rf=resultfields.sort

cutoff = 40

todocnt = len(todoPif)

outQ = Queue()
hdrQ = Queue()

# output file
gpif = '/media/sf_samplePifs/test2.gpif'

append = 0

if __name__ == '__main__':

    # this is a little trick I picked up off the internet for passing multiple queues.  works ok
    todopool = Pool(None,nodb.poolQueueInit,[outQ,hdrQ])

    # itertools used to create an arg that contains a constant (ff) for all calls)
    r = todopool.map_async(nodb.deRefCall,itertools.izip(todoPif, itertools.repeat(ff)),1)

    while (True):
        nodb.logging.info('number left: ' + str(r._number_left) + '\nready? ' + str(r.ready()))
        nodb.logging.info('queue size: ' + str(outQ.qsize()))

        if (r._number_left == 0): break
        if (outQ.qsize() >= cutoff):
            nodb.dumpQueueToGpif(gpif, hdrQ, outQ, append, cutoff)
            if (append == 0): 
                append = 1

        sys.stderr.write('\rPIF Files DONE: ' + str(todocnt-r._number_left) + '/' + str(todocnt))
        print '\n'
        time.sleep(0.2)
    r.wait()  

sys.stderr.write('\rPIF Files DONE: ' + str(todocnt) + '/' + str(todocnt) + '\n')

# dump remainder to file
nodb.dumpQueueToGpif(gpif, hdrQ, outQ, append,outQ.qsize())
主要新增内容:

在另一个用户的请求下,我简化了代码。无队列、无外部专用库等:

import sys
import os
import time
from multiprocessing import Pool

def doPifFile(pifFile):

    #readPif = call(['ls','-l',' > /tmp/out'])
    cmd = 'ipdr_dump ' + pifFile + ' | grep "," | wc -l > /tmp/dump'
    readPif = os.system(cmd)
    return readPif

def getFileList(directory):
    flist = list()
    for root, dirs, files in os.walk(directory):
        for piffile in files:
            if piffile.endswith('.pif'):
                flist.append(os.path.abspath(os.path.join(root,piffile)))
    return flist

todoPif = getFileList('/data/david/data/2012/05')

todocnt = len(todoPif)
print '# of files to process: ' + str(todocnt)

if __name__ == '__main__':

    todopool = Pool()
    r = todopool.map_async(doPifFile,todoPif,1)

    while (True):
        print 'number left: ' + str(r._number_left) + '\nready? ' + str(r.ready())

        #if (r.ready()): break
        if (r._number_left == 0): break
        sys.stderr.write('\rPIF Files DONE: ' + str(todocnt-r._number_left) + '/' + str(todocnt))
        print '\n'
        time.sleep(0.2)

sys.stderr.write('\rPIF Files DONE: ' + str(todocnt) + '/' + str(todocnt) + '\n')
当我运行它时,我得到了一些非常有趣的东西,这些东西在运行更复杂的代码时并没有出现,但发生在完全相同的位置,尽管它声称它发生在我的转储程序中:

number left: 533100
ready? False
PIF Files DONE: 62100/595200

number left: 533090
ready? False
PIF Files DONE: 62110/595200

*** glibc detected *** ipdr_dump: corrupted double-linked list: 0x0000000001a58370 ***
======= Backtrace: =========
/lib64/libc.so.6[0x36f5c76126]
/lib64/libc.so.6[0x36f5c78eb4]
/lib64/libc.so.6(fclose+0x14d)[0x36f5c6678d]
/lib64/libz.so.1[0x36f6803021]
ipdr_dump[0x405c0b]
ipdr_dump[0x40546e]
ipdr_dump[0x401c2a]
/lib64/libc.so.6(__libc_start_main+0xfd)[0x36f5c1ecdd]
ipdr_dump[0x4016b9]
======= Memory map: ========
00400000-0040e000 r-xp 00000000 08:02 2364135                            /home/david/ipdr_dump
0060d000-0060e000 rw-p 0000d000 08:02 2364135                            /home/david/ipdr_dump
01a54000-01a75000 rw-p 00000000 00:00 0                                  [heap]
32e0600000-32e0604000 r-xp 00000000 08:02 3932181                        /lib64/libuuid.so.1.3.0
32e0604000-32e0803000 ---p 00004000 08:02 3932181                        /lib64/libuuid.so.1.3.0
32e0803000-32e0804000 rw-p 00003000 08:02 3932181                        /lib64/libuuid.so.1.3.0
36f5800000-36f5820000 r-xp 00000000 08:02 3932309                        /lib64/ld-2.12.so
36f5a1f000-36f5a20000 r--p 0001f000 08:02 3932309                        /lib64/ld-2.12.so
36f5a20000-36f5a21000 rw-p 00020000 08:02 3932309                        /lib64/ld-2.12.so
36f5a21000-36f5a22000 rw-p 00000000 00:00 0 
36f5c00000-36f5d8a000 r-xp 00000000 08:02 3932315                        /lib64/libc-2.12.so
36f5d8a000-36f5f89000 ---p 0018a000 08:02 3932315                        /lib64/libc-2.12.so
36f5f89000-36f5f8d000 r--p 00189000 08:02 3932315                        /lib64/libc-2.12.so
36f5f8d000-36f5f8e000 rw-p 0018d000 08:02 3932315                        /lib64/libc-2.12.so
36f5f8e000-36f5f93000 rw-p 00000000 00:00 0 
36f6000000-36f6002000 r-xp 00000000 08:02 3932566                        /lib64/libdl-2.12.so
36f6002000-36f6202000 ---p 00002000 08:02 3932566                        /lib64/libdl-2.12.so
36f6202000-36f6203000 r--p 00002000 08:02 3932566                        /lib64/libdl-2.12.so
36f6203000-36f6204000 rw-p 00003000 08:02 3932566                        /lib64/libdl-2.12.so
36f6400000-36f6417000 r-xp 00000000 08:02 3932564                        /lib64/libpthread-2.12.so
36f6417000-36f6617000 ---p 00017000 08:02 3932564                        /lib64/libpthread-2.12.so
36f6617000-36f6618000 r--p 00017000 08:02 3932564                        /lib64/libpthread-2.12.so
36f6618000-36f6619000 rw-p 00018000 08:02 3932564                        /lib64/libpthread-2.12.so
36f6619000-36f661d000 rw-p 00000000 00:00 0 
36f6800000-36f6815000 r-xp 00000000 08:02 3932563                        /lib64/libz.so.1.2.3
36f6815000-36f6a14000 ---p 00015000 08:02 3932563                        /lib64/libz.so.1.2.3
36f6a14000-36f6a15000 r--p 00014000 08:02 3932563                        /lib64/libz.so.1.2.3
36f6a15000-36f6a16000 rw-p 00015000 08:02 3932563                        /lib64/libz.so.1.2.3
36f6c00000-36f6c83000 r-xp 00000000 08:02 3932493                        /lib64/libm-2.12.so
36f6c83000-36f6e82000 ---p 00083000 08:02 3932493                        /lib64/libm-2.12.so
36f6e82000-36f6e83000 r--p 00082000 08:02 3932493                        /lib64/libm-2.12.so
36f6e83000-36f6e84000 rw-p 00083000 08:02 3932493                        /lib64/libm-2.12.so
36f7000000-36f7007000 r-xp 00000000 08:02 3935994                        /lib64/librt-2.12.so
36f7007000-36f7206000 ---p 00007000 08:02 3935994                        /lib64/librt-2.12.so
36f7206000-36f7207000 r--p 00006000 08:02 3935994                        /lib64/librt-2.12.so
36f7207000-36f7208000 rw-p 00007000 08:02 3935994                        /lib64/librt-2.12.so
36f7800000-36f781d000 r-xp 00000000 08:02 3932588                        /lib64/libselinux.so.1
36f781d000-36f7a1c000 ---p 0001d000 08:02 3932588                        /lib64/libselinux.so.1
36f7a1c000-36f7a1d000 r--p 0001c000 08:02 3932588                        /lib64/libselinux.so.1
36f7a1d000-36f7a1e000 rw-p 0001d000 08:02 3932588                        /lib64/libselinux.so.1
36f7a1e000-36f7a1f000 rw-p 00000000 00:00 0 
36f7c00000-36f7c16000 r-xp 00000000 08:02 3932572                        /lib64/libresolv-2.12.so
36f7c16000-36f7e16000 ---p 00016000 08:02 3932572                        /lib64/libresolv-2.12.so
36f7e16000-36f7e17000 r--p 00016000 08:02 3932572                        /lib64/libresolv-2.12.so
36f7e17000-36f7e18000 rw-p 00017000 08:02 3932572                        /lib64/libresolv-2.12.so
36f7e18000-36f7e1a000 rw-p 00000000 00:00 0 
36f8000000-36f800e000 r-xp 00000000 08:02 3935998                        /lib64/liblber-2.4.so.2.5.6
36f800e000-36f820d000 ---p 0000e000 08:02 3935998                        /lib64/liblber-2.4.so.2.5.6
36f820d000-36f820e000 r--p 0000d000 08:02 3935998                        /lib64/liblber-2.4.so.2.5.6
36f820e000-36f820f000 rw-p 0000e000 08:02 3935998                        /lib64/liblber-2.4.so.2.5.6
36f8800000-36f8849000 r-xp 00000000 08:02 3932243                        /lib64/libldap-2.4.so.2.5.6
36f8849000-36f8a49000 ---p 00049000 08:02 3932243                        /lib64/libldap-2.4.so.2.5.6
36f8a49000-36f8a4b000 r--p 00049000 08:02 3932243                        /lib64/libldap-2.4.so.2.5.6
36f8a4b000-36f8a4d000 rw-p 0004b000 08:02 3932243                        /lib64/libldap-2.4.so.2.5.6
36f8c00000-36f8c16000 r-xp 00000000 08:02 3936000                        /lib64/libgcc_s-4.4.7-20120601.so.1
36f8c16000-36f8e15000 ---p 00016000 08:02 3936000                        /lib64/libgcc_s-4.4.7-20120601.so.1
36f8e15000-36f8e16000 rw-p 00015000 08:02 3936000                        /lib64/libgcc_s-4.4.7-20120601.so.1
36f9400000-36f9535000 r-xp 00000000 08:02 4206136                        /usr/lib64/libnss3.so
36f9535000-36f9734000 ---p 00135000 08:02 4206136                        /usr/lib64/libnss3.so
36f9734000-36f9739000 r--p 00134000 08:02 4206136                        /usr/lib64/libnss3.so
36f9739000-36f973b000 rw-p 00139000 08:02 4206136                        /usr/lib64/libnss3.so
36f973b000-36f973d000 rw-p 00000000 00:00 0 
36f9800000-36f9825000 r-xp 00000000 08:02 4206135                        /usr/lib64/libnssutil3.so
36f9825000-36f9a24000 ---p 00025000 08:02 4206135                        /usr/lib64/libnssutil3.so
36f9a24000-36f9a2a000 r--p 00024000 08:02 4206135                        /usr/lib64/libnssutil3.sonumber left: 533078
ready? False
PIF Files DONE: 62122/595200

number left: 533068
ready? False
PIF Files DONE: 62132/595200

number left: 533056
ready? False
PIF Files DONE: 62144/595200
奇怪的是,它继续运行,而之前的运行导致了_number_left的故障和“ready()”的缺火(尽管进程仍然在后台运行)

我已经在我拥有的16处理器盒上手动运行了转储程序,它们并行运行良好,以前从未见过glibc错误。我必须假设它与python设置相关联……我只是不知道在哪里

这对于论坛诊断来说可能太复杂了。任何关于我可能去哪里看或者我如何能够看到发生了什么的进一步想法都是受欢迎的

又一个花絮…打印出来的池。\u成功。当_number_左停止移动时,它会在神奇的时刻变为FALSE

INFO  number left: 533167  
ready? False  
successful? True  
INFO  queue size: 424  
PIF Files DONE: 62033/595200  

INFO  number left: 533117
ready? False
successful? True
INFO  queue size: 424
PIF Files DONE: 62083/595200

INFO  number left: 533087
ready? True
successful? False
INFO  queue size: 424
PIF Files DONE: 62113/595200

INFO  number left: 533087
ready? True
successful? False
INFO  queue size: 424
PIF Files DONE: 62113/595200

你可以试试sys.stdout.flush()。

经过很多努力,我发现了问题……至于问题的原因,我还不能确定。看起来像只虫子

下面是几个高级命令,因此我接下来解释的内容更有意义(这并不意味着是可执行的):

回想一下,args是一个包含595200个文件名的列表

我开始研究r._值,在我的例子中,它是一个长度为595200的列表。我注意到问题出现时,值发生了变化……所以我查看了类型

以下是我最近一次运行的输出:

INFO  number left: 533148 <- based on r._number_left
<type 'list'>             <- print type(r._value)
PIF Files DONE: 62052/595200

INFO  number left: 533096
<type 'list'>
PIF Files DONE: 62104/595200

INFO  number left: 533087
<class 'nodb_v09e.pifReaderEOFReached'>
PIF Files DONE: 62113/595200

INFO  number left: 533087
<class 'nodb_v09e.pifReaderEOFReached'>
PIF Files DONE: 62113/595200

INFO number left:533148另一个注意事项:我正在使用2.7.3,通过在机器上编译的pypy。哦,我让它运行到完成。最初,“while true”循环查找pool.ready()是否为true,然后它就会爆发。问题是它在完成之前就实现了。删除该检查可以让它运行到完成,接触所有595k文件,但它从未离开检查循环。因此,代码的“修复”是删除该检查,我认为它会很好地完成……但不会有用户对流程状态的反馈。您能尝试减少问题吗?在一个不使用nodb或netaddr的示例中,您还看到了吗?我开始创建一个简短的版本,只转储文件…不匹配等。将在此处简短地发布结果最可能的是,不应该直接访问以下划线开头的名称(如
\u value
)。如果你使用更正式的界面,我相信你会得到更一致的结果。我也有同样的问题。你知道发生了什么事吗?
INFO  number left: 533148 <- based on r._number_left
<type 'list'>             <- print type(r._value)
PIF Files DONE: 62052/595200

INFO  number left: 533096
<type 'list'>
PIF Files DONE: 62104/595200

INFO  number left: 533087
<class 'nodb_v09e.pifReaderEOFReached'>
PIF Files DONE: 62113/595200

INFO  number left: 533087
<class 'nodb_v09e.pifReaderEOFReached'>
PIF Files DONE: 62113/595200