2011-08-22 78 views
2

當試圖使用2.5.2上的python多處理模塊CentOS 5.5在多個核心之間分割數據庫插入時,整個16個進程池一旦完成就會中止。我認爲使用pool.close/pool.join應該可以防止發生這種情況。python 2.5.2多處理池行爲

def insert(): 
    blocksize=lines/ncpus 
    i=0 
    while i<lines: 
     print 'writing block %d to %d' % (i,i+blocksize+ncpus) 
     pool.apply_async(write_db, (i,i+blocksize+ncpus,query,)) 
     i+=blocksize+ncpus 
    pool.close() 
    pool.join() 

def write_db(start,stop,q): 
    ctr=0 
    odbcstring"...." 
    con = pyodbc.connect(odbcstring) 
    cur = con.cursor() 

    commitlock = multiprocessing.Lock() 

    for j in range(start,stop): 
     try: 
      cur.execute(q[j]) 
      ctr+=1 
      if (ctr%10000)==0: 
       commitlock.acquire() 
       con.commit() 
       commitlock.release() 
     except: 
      print get_exception_info()   

    commitlock.acquire() 
    con.commit() 
    commitlock.release() 
    con.close() 

我理論化,它有東西從pool.apply docs做這樣一句話: 此外,在功能只在游泳池裏的一名工人

也許還有通過執行是內置MP和我不知道的MP模塊之間的一些區別。

感謝您的幫助。

+0

當你說它「在第一次完成時立即中止」,「中止」意味着什麼?有錯誤嗎?你確定所有其他預期的過程都在運行嗎?你有沒有嘗試添加一些日誌/打印語句來調試它? – Gerrat

+0

我已確認每個進程都在每次提交之前插入調試語句並驗證數據是否確實正在寫入數據庫。它不會以錯誤結束;所有未完成的正在運行的進程都會被終止。另外,我已經注意到,有時候,通過在write_db的末尾插入最終的打印語句,有時會有多個進程完成。感謝您的持續幫助。 – jordanpg

+0

嘗試在write_db方法中的'all'代碼中包裝try/except子句(並打印出發生的任何異常)。如果有某種數據庫問題(如超過最大連接數),可能會導致您遇到的問題。 – Gerrat

回答

0

我不確定這是否與您的問題有關,但是您在創建的每個進程中創建了一個新的 multiprocessing.Lock對象。
...所以獲取這個鎖定你的連接提交不會做任何事情。

[編輯爲了在進程間共享這個鎖,你需要一個管理器對象:

manager = multiprocessing.Manager() 
lock = manager.Lock() 

現在,你應該能夠通過這個鎖作爲參數傳遞給你的進程。

+0

謝謝你指出。我試着運行相同的代碼,只用相同的結果註釋掉鎖,所以我不認爲這是問題所在。 – jordanpg

+0

這很好地建立鎖。但是我從來沒有讓游泳池工作,只是使用單獨的進程。 – jordanpg