2017-07-28 77 views
0

我遇到了一個問題,它使用最新的python 3.5軟件包及其tarfile模塊創建新的tarfiles。這個問題類似於討論的那些herehere。在前一種情況下,建議的解決方案返回錯誤ReadError: empty header,而在後一種情況下,這是八年前的一個封閉問題,應該已經通過加載最新版本的語言來應用該補丁。 Tarfile模塊的文檔明確聲明「a」可用於創建新的tarfiles。Python 3.5:tarfile在空焦油上附加模式「ReadError」

這個問題特別出現在嘗試創建新的tarfile的情況下。生成它的代碼將在下面完整地複製;我正在使用一個簡單的腳本來對多處理中的任務進行基準測試。

#just a little script to test copy times for a control 

import os 
import os.path 
import time 
import shutil 
import multiprocessing 
import tarfile 

global source; source = "/home/patches/Documents/Scripting Projects/Resources/Test Payload" 
global dest; dest = "/home/patches/Desktop/Copy Benchmark 
Output.tar.bz2" 
global start 
global end 
global diff 
global testing; testing = True 
global numConsumers; numConsumers = multiprocessing.cpu_count() 


#Classes! 
class copyProc(multiprocessing.Process): 
    def __init__(self, qTask): 
     multiprocessing.Process.__init__(self) 
     self.qTask = qTask 
     os.chdir(source) 

    def run(self): 
     proc_name = self.name 
     while True: 
      next_task = self.qTask.get() 
      if next_task is None: 
       # Poison pill means shutdown 
       print('%s: Exiting' % proc_name) 
       self.qTask.task_done() 
       break 
      next_task() 
      self.qTask.task_done() 
     return 

class copyJob(object): 
    def __init__(self, a): 
     self.tgt = a 
    def __call__(self): 
     tar = tarfile.open(dest, "a") 
     tar.add(self.tgt) 
     tar.close() 

#Function 
def announce(): 
    print("Starting copy benchmark - multiprocessing.") 
    foo = input("Press any key to begin") 

def startTimer(): 
    global start 
    start = time.time() 


def setup(): 
    os.chdir(source) 
    for a, b, files in os.walk(source): 
     for file in files: 
     tasks.put(copyJob(file)) 
    for i in range(numConsumers): 
     tasks.put(None) 

def endTimer(): 
    global end 
    end = time.time() 

def prompt(): 
    diff = end - start 
# os.remove(dest) 
    print("The test took %s seconds" % str(diff)) 
    bar = input("Run again? Y/n") 
    if bar == "n": 
     testing = False 

#runtime 
if __name__ == '__main__': 
    multiprocessing.set_start_method("spawn") 
    tasks = multiprocessing.JoinableQueue() 
    announce() 
    startTimer() 
    setup() 
consumers = [] 
for i in range(numConsumers): 
    consumers.append(copyProc(tasks)) 
for w in consumers: 
    w.start() 
tasks.join() 
endTimer() 
prompt() 

編輯補充:這個問題具體爲,而不是具體的行爲,該腳本,而不是拋出一個「ReadError:空頭」的異常上試圖打開tar文件。

+0

問題是? – user2722968

+0

是的,你說的對,明確表示會有所幫助。我已經修改了這個問題。具體問題在底部。 – zPatches

回答

0

所以事實證明,問題是有多個進程試圖或多或少地同時打開文件導致了這個問題。解決方案是使用某種形式的鎖定來防止這種情況。

在我的情況下,我使用了一個簡單的multiprocessing.Lock()對象,然後在進行追加和釋放之前先獲取它。該解決方案仍然比在單個進程中執行所有附件更快。不知道爲什麼。

我希望如果像我一樣有這個問題,那麼這個解決方案也適用於您。