Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/google-sheets/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 确保subprocess.Popen调用的执行顺序_Python_Synchronization - Fatal编程技术网

Python 确保subprocess.Popen调用的执行顺序

Python 确保subprocess.Popen调用的执行顺序,python,synchronization,Python,Synchronization,我正在使用subprocess.Popen为Scipy堆栈创建一个自动构建脚本 我目前的进程如下 mathbuild.json: {"suitesparse": {"version": "4.2.1", "dependencies": ["metis"], "downloads": ["http://www.cise.ufl.edu/research/sparse/SuiteSparse/SuiteSparse-4.2.1.tar.gz"],

我正在使用subprocess.Popen为Scipy堆栈创建一个自动构建脚本

我目前的进程如下

mathbuild.json:

{"suitesparse": {"version": "4.2.1",
         "dependencies": ["metis"],
         "downloads": ["http://www.cise.ufl.edu/research/sparse/SuiteSparse/SuiteSparse-4.2.1.tar.gz"],
         "build": ["cd $DL_DIR",
               "tar xvfz SuiteSparse-4.2.1.tar.gz",
               "cd SuiteSparse",
               "cp -r $DL_DIR/metis-4.0.3 metis-4.0.3"]},

 "metis": {"version": "4.0.3",
       "dependencies": [],
       "downloads": ["http://glaros.dtc.umn.edu/gkhome/fetch/sw/metis/OLD/metis-4.0.3.tar.gz"],
       "build": ["cd $DL_DIR",
             "tar xvfz metis-4.0.3.tar.gz",
             "cd metis-4.0.3",
             "make"]}}
mathbuild.py:

def package_list(package, config):
    for dependency in config[package]['dependencies']:
        yield from package_list(dependency, config)
    yield package

def build_package(package, config):
    command = '; '.join(config[package]['build'])
    build = subprocess.Popen(command, shell=True)


def process_package(package, config, env_dir, dl_dir):
    print('INSTALLING {0}'.format(package))
    print('Downloading...')
    download_package(package, config, dl_dir)
    print('Building...')
    build_package(package, config)


if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Install Pylab in a new venv.')
    parser.add_argument('env_dir', help='target directory for new environment')
    args = parser.parse_args()
    os.environ['ENV_DIR'], os.environ['DL_DIR'] = create_venv(args.env_dir)
    with open('mathbuild.json') as f:
        cfg = json.load(f)
    processed = []
    for package in package_list('suitesparse', cfg):
        if package not in processed:
            process_package(package, cfg,
                            os.environ['ENV_DIR'],
                            os.environ['DL_DIR'])
            processed += [package]
它创建一个依赖项列表(以便后面的项依赖于前面的项),然后处理每个依赖项(下载,然后根据json文件中的命令构建)

问题是在依赖关系完全构建之前,包是通过新的
子流程.Popen
调用构建的。在上面的示例中,
suitesparse
执行甚至在
metis
构建完成之前就开始了。我假设这是因为我每次在包列表('suitesparse',cfg)中为包打开一个新的子流程,而不考虑前面的子流程是否完成

问题 同步基于循环的Popen调用的最佳方法是什么,以便每次调用仅在前一次Popen调用(即列表中的前一项)完成时启动

我尝试过的
我尝试更改循环,使其生成一个组合的Popen(使用两个包生成),但这似乎有点不太妥当。

看起来您需要
子流程。请检查调用()
,而不是Popen。发件人:

使用参数运行命令。等待命令完成。如果返回代码为零,则返回,否则引发CalledProcessError

您的构建函数将类似于:

def build_package(package, config):
    command = '; '.join(config[package]['build'])
    subprocess.check_call(command, shell=True)
如果实际使用的是Popen对象,则可以调用
wait()
方法来等待子命令完成:

def build_package(package, config):
    command = '; '.join(config[package]['build'])
    build = subprocess.Popen(command, shell=True)
    # do something with the build object
    build.wait()
    # command is done