通知python脚本进程已完成

通知python脚本进程已完成,python,subprocess,Python,Subprocess,首先,让我说这是我第一次使用python,我对并行计算一无所知,所以我的问题可能有点傻 一位朋友在CentOS 5.5上运行的群集上运行一些模拟。对于每一次运行,程序(tripoli)需要3个文件作为输入。第一个文件包含要处理的数据,第二个文件是输出文件(将结果存储在此文件中),第三个文件是指示如何在集群上分配工作负载的文件(graph.save) 从一次运行到另一次运行,唯一需要更改的是输入文件中的特定行。这是第14.176行。我将该行的所有可能值存储在不同的文件中。我叫它同位素档案 到目前为

首先,让我说这是我第一次使用python,我对并行计算一无所知,所以我的问题可能有点傻

一位朋友在CentOS 5.5上运行的群集上运行一些模拟。对于每一次运行,程序(tripoli)需要3个文件作为输入。第一个文件包含要处理的数据,第二个文件是输出文件(将结果存储在此文件中),第三个文件是指示如何在集群上分配工作负载的文件(graph.save)

从一次运行到另一次运行,唯一需要更改的是输入文件中的特定行。这是第14.176行。我将该行的所有可能值存储在不同的文件中。我叫它同位素档案

到目前为止,我的逻辑是。打开同位素文件。获取所有数据。对于同位素[1],打开输入文件。将同位素[1]写入输入文件[14175]。关闭输入文件。为此输入文件运行程序。一旦你完成了重复同位素[2]。每次跑步大约需要50到60分钟

我想通过轮询qhost命令来查看节点负载何时低于阈值(例如0.5%),从而判断是否完成了计算,但这似乎是一种糟糕的做法

我希望subprocess.call的行为与下面的
subprocess.call(“C:\Windows\System32.calc.exe”)
一样(启动calc并在那里停止,直到calc关闭)。我的意思是,我预计的黎波里将开始运行,python将停止运行,直到的黎波里的计算结束。但事实并非如此。一旦我点击run,tripoli将启动数据文件中的行数

我错过了什么

到目前为止我掌握的代码

import os
import os.path
import re
import datetime
import subprocess

def getLinesfromFile(filetobeOp, mode):
    with open (filetobeOp, mode) as temp:
      data = temp.readlines()
      temp.close()
return data


isotope = getLinesfromFile('isotopes','r')

for i, element in enumerate(isotope):
    runs+=1
    data = getLinesfromFile('inputfile','r')
    data[14175]="\t"+element
    tempElement = element.replace("\n", "")
    commandRunTripoli = "./run.sh inputfile "+tempElement.rsplit(' ', 1)[0]+".out    graphe.save"

    with open('tmt','w') as f2:
        f2.writelines(data)
        f2.close()

    subprocess.call(commandRunTripoli)

    print(datetime.datetime.now())
    print("Tripoli run #", runs, "with isotope::", element)
run.sh文件包含以下内容

#!/bin/sh                                                                                                                                                                                                                        
#export LD_LIBRARY_PATH=/usr/local/TRIPOLI-4.8/CODE/lib/linux-intel-      4:$LD_LIBRARY_PATH

\rm -f *.update graphe graphe.port last_simulation*
mpirun  /home/nefeli/.tripoli48/Exec/bin/linux-intel-64/static_tripoli4 -d   $1 -s NJOY -c /home/nefeli/.tripoli48/Exec/Env/t4path.ceav5 -o  $2 -p $3 -t bsd  &
\rm -f *.update graphe graphe.port last_simulation*

正如kjp指出的那样,问题在于我将进程发送到后台(&在.sh文件中)。我的朋友使用ssh连接到服务器并运行模拟。一个模拟需要时间(大约60分钟),而且有很多模拟要做。因此,如果笔记本电脑断电,连接将丢失,进程将终止。我认为他可以使用nohup和符号(nohup-python3-script.py&)运行脚本,这样即使在连接断开后,进程也会继续执行,但是nohup不是和&?我的意思是,如果我使用nohup运行命令,我是否会将进程发送到后台,从而导致脚本出现故障

问题是shell将mpirun放在后台并立即返回,如果要等到mpirun完成其运行,请删除结尾处的&

mpirun  /home/nefeli/.tripoli48/Exec/bin/linux-intel-64/static_tripoli4 -d   $1 -s NJOY -c /home/nefeli/.tripoli48/Exec/Env/t4path.ceav5 -o  $2 -p $3 -t bsd  &

我不明白上面的代码如何参与到您描述的行为中。只有一个子流程调用,而且它不在循环中,所以它怎么会发生多次呢?你确定上面的缩进是正确的吗?缩进在Python中非常重要。哦,我把它粘贴到这里时把它搞砸了。我没有注意到它。它在py文件中是正确的。谢谢你,run.sh启动的黎波里进程然后退出有可能吗?这可以解释你所看到的行为。如果您还发布了run的内容,这将非常有用。sh@dbw我会说是的。某些文件中的重复表示同时运行多个实例。请使用screen或tmux运行python脚本,以允许随意使用
ssh
。无关:将列表传递给
子流程.call()
例如
调用(['program','arg 1','arg 2'])
。如果将
-语句一起使用,请不要调用
.close()
:即使出现异常,
-语句的作用是关闭文件。尝试一次解决一个问题。call()等待命令完成并返回返回代码。这相当于运行您发布的第一个命令,没有不安全/危险的shell=True。为什么我需要添加process.wait?我想,电话就是这样。无论如何,我试过了,但没有成功。@dbw u r是的,我刚刚测试过,它确实在等待进程返回。@Silas-问题是您的命令立即返回-请参阅结尾处的-,它将mpirun放在后台并立即返回。如果您的shell返回而不等待mpirun.Yes,则子进程无法等待。就这样。我从来没有想过要在run.sh中找到这样的东西。非常感谢你。