2017-07-28 83 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()对象,然后在进行追加和释放之前先获取它。该解决方案仍然比在单个进程中执行所有附件更快。不知道为什么。

我希望如果像我一样有这个问题,那么这个解决方案也适用于您。