2

I searchedon internet and learned other method of implementing it the problem now i have found out. my execution time always becomes more than that of time out if i write stdout=subprocess.PIPE in subprocess.Popen. If i am removing it then it is taking normal execution time

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 

3 Answers 3

3

You shouldn't spawn a new thread just for having it time out in 5 seconds and then use it's isAlive status as break condition for a busy wait. You don't need an extra thread for that, you can messure the time in the first thread.

Instead of polling the thread as often as you can, you should use a delay (time.sleep) to allow the processor to do some real work.

And you should know that if your process is generating a lot of output, it will block if you don't read it while the process is executing and let it fill up the pipe's buffer.

Sign up to request clarification or add additional context in comments.

4 Comments

I searched internet and found other way of implementing it. thanks for your reply.Now i am having problem with stdout=subprocess.PIPE. If i write it then it is taking more execution time else normal execution time.
@KevalVora - you still seem to read the pipe only after the process has finnished. If the pipe's buffer is full, then the subprocess will hang until you read from it or it is killed. And using time.time instead of datetime would be faster.
I need to run the program submitted by user and check whether it has executed successfully or not if there is infinite loop i need to kill that process and I need to show the output to the user. can you suggest any solution for this?
yes, just read the output (stdout/stdin) while the process is running. that is something you could do in a second thread.
1
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"]) 

Comments

0

Thread can be handled in python VM, but process not. so u have to use OS api to kill ur process/subprocess, such as (in linux):

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

and, using thread for timing is a bad idea. how about:

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) 

1 Comment

I searched internet and found other way of implementing it. thanks for your reply.Now i have updated my question and i am having problem with stdout=subprocess.pipe.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.