Python subprocess.check_call([“wine”] ..)有一个同步问题

时间:2017-08-11 12:44:15

标签: python python-3.x subprocess race-condition wine

我有一个python脚本,使用subprocess.check_call启动Wine(Linux上的Windows Emulator),然后葡萄酒启动Z:\\Program Files (x86)\\PeaZip\\peazip.exe

首先,当我在调试模式python3 -u -m ipdb unpack_archive.py中测试这个python脚本,并逐步设置葡萄酒启动和运行语句的断点时,Wine成功运行peazip.exe。也就是说,peazip成功地在Linux上提取了PEA档案。

但是,当我在调试模式python3 unpack_archive.py中测试这个python脚本时,我发现peazip.exe没有成功提取PEA存档。所以我怀疑wine或python subprocess.check_call()中存在同步问题。

现在我的解决方法是,在启动葡萄酒后插入time.sleep(1.0)

elif 'PEA archive' in ftype:
    if splitext(arcname)[1] != '.pea':
        tmpfile = os.path.join(tmpdir, basename(arcname))+'.pea'
    else:
        tmpfile = os.path.join(tmpdir, basename(arcname))
    shutil.copy(arcname, tmpfile)
    subprocess.check_call(["wine", "/home/acteam/.wine/drive_c/Program Files (x86)/PeaZip/peazip.exe",
        "-ext2here", to_wine_path(tmpfile)])
    import time
    time.sleep(1.0) # if we don't sleep, then peazip.exe won't extract file successfully 
    os.remove(tmpfile)
    copy_without_symlink(tmpdir, outdir)

我检查了wine manual,它没有提到有关同步的任何内容。我还检查了subprocess.check_call()。该文档明确说明check_call()将等待命令完成。

我不希望这种解决方法,因为如果PEA归档文件非常大,那么sleep()的超时值必须更大,并且我们无法在运行它之前预测足够的超时值。

我提到了@jasonharper的建议。使用subprocess.check_output()而不是check_call()

    elif 'PEA archive' in ftype:
        if splitext(arcname)[1] != '.pea':
            tmpfile = os.path.join(tmpdir, basename(arcname))+'.pea'
        else:
            tmpfile = os.path.join(tmpdir, basename(arcname))
        shutil.copy(arcname, tmpfile)
        subprocess.check_output(["wine", "/home/acteam/.wine/drive_c/Program Files (x86)/PeaZip/peazip.exe",
            "-ext2here", to_wine_path(tmpfile)])
        os.remove(tmpfile)
        copy_without_symlink(splitext(tmpfile)[0], outdir)

我用python3 unpack_archive.py Kevin.pea测试了它,这是一个2.0GB的PEA档案。提取过程花费4分16秒。三个子文件已成功解压缩。

0 个答案:

没有答案