2012-05-24 7 views
2

나는 인터넷을 검색하여 그것을 구현하는 다른 방법을 배웠다. 이제 문제를 발견했다. 내 실행 시간은 항상 그 이상이된다 시간이 나가면 stdout = subprocess.PIPE subprocess.Popen. 내가 그것을 제거하고 경우 다음 당신은 단 5 초에 시간을 가지고위한 새로운 스레드를 생성 한 후 바쁜 대기를위한 휴식의 조건으로 isAlive 상태의 사용해서는 안 정상 실행 시간타임 아웃 후 파이썬에서 서브 프로세스를 죽이는

import subprocess, datetime, os, time, signal 
//setting time for timeout 
timeout=3 
start = datetime.datetime.now() 
process = subprocess.Popen(["python", "/home/bourne/untitled.py"],shell=False, stdout=subprocess.PIPE,stderr=subprocess.PIPE) 
while process.poll() is None: 
     time.sleep(0.1) 
     now = datetime.datetime.now() 
     if (now - start).seconds > timeout: 
      os.kill(process.pid, signal.SIGKILL) 
      os.waitpid(-1, os.WNOHANG) 
      print "error"  
      print (now - start).seconds 
      break 
     print (now - start).seconds 

답변

0
I have successfully solved the problem. the solution is 

import subprocess, signal, os, threading, errno 
from contextlib import contextmanager 

class TimeoutThread(object): 
    def __init__(self, seconds): 
     self.seconds = seconds 
     self.cond = threading.Condition() 
     self.cancelled = False 
     self.thread = threading.Thread(target=self._wait) 

    def run(self): 
     """Begin the timeout.""" 
     self.thread.start() 

    def _wait(self): 
     with self.cond: 
      self.cond.wait(self.seconds) 

      if not self.cancelled: 
       self.timed_out() 

    def cancel(self): 
     """Cancel the timeout, if it hasn't yet occured.""" 
     with self.cond: 
      self.cancelled = True 
      self.cond.notify() 
     self.thread.join() 

    def timed_out(self): 
     """The timeout has expired.""" 
     raise NotImplementedError 

class KillProcessThread(TimeoutThread): 
    def __init__(self, seconds, pid): 
     super(KillProcessThread, self).__init__(seconds) 
     self.pid = pid 

    def timed_out(self): 
     try: 
      os.kill(self.pid, signal.SIGKILL) // this is for linux you need to change it for windows 
     except OSError,e: 
      # If the process is already gone, ignore the error. 
      if e.errno not in (errno.EPERM, errno. ESRCH): 
       raise e 

@contextmanager 
def processTimeout(seconds, pid): 
    timeout = KillProcessThread(seconds, pid) 
    timeout.run() 
    try: 
     yield 
    finally: 
     timeout.cancel() 


def example(cmd): 
    proc = subprocess.Popen(cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE) 
    //setting the timeout to be 1 sec 
    with processTimeout(1, proc.pid): 
     stdout,stderr=proc.communicate()  

    resultcode = proc.wait() 
    if resultcode < 0: 
     #print "error: %i" % resultcode 
     return resultcode,0 
    else: 
     return stdout,stderr 





//This is used to create new subprocess and it will return output as well as error 
output,err=example(["python",filepath,"5"]) 
3

을하고있다. 당신은 여분의 스레드가 필요하지 않습니다, 당신은 첫 번째 스레드에서 시간을 messure 수 있습니다.

가능한 한 자주 스레드를 폴링하는 대신 지연 기 (time.sleep)를 사용하여 프로세서가 실제 작업을 수행 할 수있게해야합니다.

프로세스가 많은 출력을 생성하는 경우 프로세스가 실행되는 동안 프로세스를 읽지 않고 파이프의 버퍼를 채우면 프로세스가 출력을 많이 생성한다는 것을 알아야합니다.

+0

. 답장을 보내 주셔서 감사합니다. 지금 stdout = subprocess.PIPE에 문제가 있습니다. 만약 내가 그것을 쓰면 다른 실행 시간을 정상적인 실행 시간이 걸리고있다. – Jack

+0

@KevalVora - 프로세스가 완료된 후에 만 ​​파이프를 읽는 것 같습니다. 파이프의 버퍼가 가득 차면 하위 프로세스를 읽거나 죽일 때까지 하위 프로세스가 중단됩니다. 그리고'datetime' 대신에'time.time'을 사용하는 것이 더 빠를 것입니다. – mata

+0

사용자가 제출 한 프로그램을 실행하고 성공적으로 실행되었는지 여부를 확인해야합니다. 무한 루프가있는 경우 해당 프로세스를 종료해야하며 사용자에게 결과를 표시해야합니다. 당신은 이것에 대한 어떤 해결책을 제안 할 수 있습니까? – Jack

0

스레드는 파이썬 VM에서 처리 할 수 ​​있지만 처리 할 수는 없습니다. 타이밍 실을 사용하는 것은 좋지이다

os.system("kill -9 %s"%(proc.pid)) 

하고 : 그래서 U는 (리눅스)로서, UR 프로세스/서브 프로세스를 죽 OS의 API를 사용한다. 방법에 대해 : 나는 인터넷을 검색하고 그것을 구현하는 다른 방법을 발견

start_t = time.time() 
TIME_END, TIME_SLEEP = 5, 1 
while time.time() - start_t < TIME_END: 
    if proc.poll(): 
     break 
    time.sleep(TIME_SLEEP) 
+0

인터넷을 검색하여 다른 방법으로 구현했습니다. 귀하의 reply.Now 주셔서 감사합니다 내 질문을 업데이 트하고 난 stdout = subprocess.pipe 문제가 있습니다. – Jack

관련 문제