Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.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检查状态或终止外部进程_Python_Web_External Process - Fatal编程技术网

如何使用python检查状态或终止外部进程

如何使用python检查状态或终止外部进程,python,web,external-process,Python,Web,External Process,我有一个在web服务器上运行的python脚本。然后调用main函数,当它返回时,它只休眠几秒钟,然后再次被调用。它的目的是收集用户添加的任何新上传视频,并将其转换为webm,将中间帧作为图像和其他一些时髦的东西。我正在使用对ffmpeg的外部调用。下面的代码片段显示了我如何调用它 duration = output[durationIndex+10:durationIndex+18] durationBits = duration.split(":") lengthIn

我有一个在web服务器上运行的python脚本。然后调用main函数,当它返回时,它只休眠几秒钟,然后再次被调用。它的目的是收集用户添加的任何新上传视频,并将其转换为webm,将中间帧作为图像和其他一些时髦的东西。我正在使用对ffmpeg的外部调用。下面的代码片段显示了我如何调用它

    duration = output[durationIndex+10:durationIndex+18]
    durationBits = duration.split(":")
    lengthInSeconds = (int(durationBits[0])*60*60) + (int(durationBits[1])*60) + (int(durationBits[2]))

    child = subprocess.Popen(["ffmpeg","-y","-i",sourceVideo,"-f","mjpeg","-vframes","1","-ss",str(lengthInSeconds/2),destination], shell=True, stderr=subprocess.PIPE)
    output = ""
    while True:
        out = child.stderr.read(1)
        if out == '' and child.poll() != None:
            break
        if out != '':
            output += out

    updateSQL = "update `videos_graduatevideo` set thumbnail = '" + str(destination) + "' where `original_video` = '" + sourceVideo + "'"
    cursor.execute(updateSQL)
此脚本正在Windows atm机上运行,但在开发完成后,我可能会将其部署到Unix系统上


问题是。我需要这个python脚本来保持运行。如果ffmpeg出现问题并且我的脚本挂起,用户上传的视频将处于“挂起”状态,直到我打开python脚本。我知道我有一个特定的mov文件使ffmpeg无法确定地挂起。是否有什么方法可以检查一个进程运行了多长时间,如果它运行的时间太长,就将其关闭?

步骤1。不要使用CGI脚本。使用框架

第二步。不要在创建响应的函数中直接启动子流程。使用

这个进程一直在服务器上运行。它独立于任何框架,并且从django填充的同一个db读取数据


第二步,再一次。不要让此子进程一直运行。使用芹菜,以便在请求到达时启动,处理该请求(并且仅处理该请求),然后停止

我同意S.Lott的观点,在体系结构中考虑使用MQ似乎会使您受益,但对于这个特定问题,我认为您可以使用

对于您创建的每个进程,保存创建时间(类似于
datetime.datetime.today()
就足够了)。然后每隔一分钟左右检查一次打开的进程和时间列表,并使用Popen获取不应该存在的进程和时间。send_signal(signal)、terminate()或kill()

例如:

import time
from subprocess import Popen
from datetime import datetime
jobs = []
max_life = 600 # in seconds

def reap_jobs(jobs):
  now = datetime.datetime.today()
  for job in jobs:
    if job[0] < now - datetime.timedelta(seconds=max_life)
      job[1].kill()
      # remove the job from the list if you want. 
      # but remember not to do it while iterating over the list

for video in list_of_videos:
  time = datetime.datetime.today()
  job = Popen(...)
  jobs.append((time,child))

while True:
  reap_jobs(jobs)
  time.sleep(60)
导入时间
从子流程导入Popen
从日期时间导入日期时间
工作=[]
最大寿命=600秒
def收割作业(作业):
now=datetime.datetime.today()
工作中的工作:
如果作业[0]
看一看,它监视您指定的流程,并根据您的监视条件执行一些操作。例如,它可以监视cpu使用情况,并在cpu使用率超过50%时重新启动进程:

# code in Ruby
# copyied from the documentation
w.restart_if do |restart|   
  restart.condition(:cpu_usage) do |c|
    c.above = 50.percent
    c.times = 5
  end
end

有一个python模块,它提供一个接口,用于以可移植的方式检索所有正在运行的进程和系统利用率(CPU、磁盘、内存)的信息,实现命令行工具提供的许多功能,例如:ps、top、df、kill、free、lsof、free、netstat、ifconfig、nice、ionice、iostato、iotop、uptime、tty:。它应该会有帮助。

因为控制脚本是启动它的脚本,而且您希望根据时间而不是系统资源使用情况来终止它,所以它应该相当简单。下面是经过一些修改的示例代码;查找带有注释的行

import time
timeout = 60 #child is allowed to run for 1 minute.
duration = output[durationIndex+10:durationIndex+18]
durationBits = duration.split(":")
lengthInSeconds = (int(durationBits[0])*60*60) + (int(durationBits[1])*60) + (int(durationBits[2]))

child = subprocess.Popen(["ffmpeg","-y","-i",sourceVideo,"-f","mjpeg","-vframes","1","-ss",str(lengthInSeconds/2),destination], shell=True, stderr=subprocess.PIPE)
killtime = time.time() + timeout #timestamp after which the child process should be killed
output = ""
while True:
    out = child.stderr.read(1)
    if out == '' and child.poll() != None:
        break
    if out != '':
        output += out
    if time.time() > killtime: #check if 60 seconds have passed
        child.kill() #tell the child to exit
        raise RuntimeError("Child process still going %i seconds after launch" %killtime) #raise an exception so that updateSQL doesn't get executed

updateSQL = "update `videos_graduatevideo` set thumbnail = '" + str(destination) + "' where `original_video` = '" + sourceVideo + "'"
cursor.execute(updateSQL)

您可以将RuntimeError更改为其他内容,或者让它设置一个标志而不是引发异常,这取决于您还需要它做什么。kill()行将导致子进程死亡,但这可能不是结束它的最优雅的方式。如果将其部署在posix系统上,则可以使用os.system('kill-s15%i'%child.pid')来更优雅地杀死它

你在回答中假设了很多我使用的是django,但是这个过程一直都在服务器上运行。它独立于任何框架,从django填充的同一个db读取数据没有创建响应,只是在创建响应时填充一些db字段done@DrLazer当前位置我在回答中假设了很多,因为你在问题中没有提供太多细节。帮我们所有人一个忙,更新你的问题,使其包含所有事实。在对答案的评论中隐藏事实对其他人没有太大帮助。我提供了足够的细节来涵盖我所问的问题。我几乎不会在一个问题中为系统编写整个规范。@DrLazer:“这个讨论很愚蠢”。不,不是。如果你需要提供更多的事实,你需要更新问题。这很简单。不要指责别人假想。通过更新问题纠正假设。请不要抱怨。请更新问题以更正假设。就这些。@DrLazer:“它的内存使用量被卡在4900K上了”?真实的物理记忆?或者普通的交换空间内存被悄悄地从真实内存中交换出来并被忽略?我有完全相同的问题(我使用的是挂架而不是Django)。我编写了一个带有数据库访问的外部程序(如果你给它Django设置,你可以使用你的模型)和一个ajax轮询系统来获得结果。他得到了支持。