Hi everyone. I need some help with a subprocess.

My Python script uses the os.popen2 function to spawn a non-Python subprocess. Now it needs a way to send a Ctrl-C interrupt or something equivalent to the subprocess. Does anyone know how to do this? Thanks in advance!

Recommended Answers

All 7 Replies

You can use the signal module of python for handling these kinds of situation.

I use multiprocessing / pyprocessing as follows. Also subprocess has replaced the os.popenX functions http://blog.doughellmann.com/2007/07/pymotw-subprocess.html

import subprocess
import time
from processing import Process

class TestClass():

   def test_f(self, name):
      subprocess.call("ping www.google.com", shell=True)
         
if __name__ == '__main__':
   CT=TestClass()
   p = Process(target=CT.test_f, args=('P',))
   p.start()

   ## sleep for 5 seconds and terminate
   time.sleep(5.0)
   p.terminate()

I have all these tricks in my notes. I found all this somewhere on the web. See if it works !

# linux, mac
os.kill(pid, signal.SIGKILL)
killedpid, stat = os.waitpid(pid, os.WNOHANG)
if killedpid == 0:
  print >> sys.stderr, "ACK! PROCESS NOT KILLED?"

# windows
handle = subprocess.Popen("someprocess here", shell=False)
subprocess.Popen("taskkill /F /T /PID %i"%handle.pid , shell=True) 

#aussi
# Create a process that won't end on its own
import subprocess
process = subprocess.Popen(['python.exe', '-c', 'while 1: pass'])


# Kill the process using pywin32
import win32api
win32api.TerminateProcess(int(process._handle), -1)


# Kill the process using ctypes
import ctypes
ctypes.windll.kernel32.TerminateProcess(int(process._handle), -1)


# Kill the proces using pywin32 and pid
import win32api
PROCESS_TERMINATE = 1
handle = win32api.OpenProcess(PROCESS_TERMINATE, False, process.pid)
win32api.TerminateProcess(handle, -1)
win32api.CloseHandle(handle)


# Kill the proces using ctypes and pid
import ctypes
PROCESS_TERMINATE = 1
handle = ctypes.windll.kernel32.OpenProcess(PROCESS_TERMINATE, False, process.pid)
ctypes.windll.kernel32.TerminateProcess(handle, -1)
ctypes.windll.kernel32.CloseHandle(handle)

I have a python process already running. Now, I want to stop that process but before that i want to save all it's state. For that, I have a CLI from where i pass the PID of that python process. Now, from the CLI, i want to kill that process. When the process gets the kill/terminate command , it should save its state in a file and terminate itself. How is it possible? Logic for saving the state is not a problem so just ignore it. But do suggest me how to make it aware that it should save before getting killed?

Hi, I need help for using Python to calculate BMI(a person’s weight) question.

Thanks

I have a python process already running. Now, I want to stop that process but before that i want to save all it's state. For that, I have a CLI from where i pass the PID of that python process. Now, from the CLI, i want to kill that process. When the process gets the kill/terminate command , it should save its state in a file and terminate itself. How is it possible? Logic for saving the state is not a problem so just ignore it. But do suggest me how to make it aware that it should save before getting killed?

If you have the signal module, you could try to install a signal handler in your process with the function signal.signal . Also, according to the documentation of signal, the signal SIGINT is transformed by python into a KeyboardInterrupt exception, so you could kill your process with a SIGINT and wrap the main task of your program in a try ... except KeyboardInterrupt statement.

The other way is to give your process a way to communicate with the outer world. This is my prefered solution for these situations. Your process could listen in a socket, or better, you could start a pyro nameserver and your process could register a pyro object to the nameserver. This allows other processes to interact very easily with a running process. You would then write a small script devoted to stopping the process.

You can save the state to a dictionary as the process is running, and use the dictionary in whatever way after that pid is terminated. I can't take much time now, so ask if there are other questions (docs are here http://pyprocessing.berlios.de/ ). A simple example of dictionary use.

import time
from processing import Process, Manager

def test_f(test_d):
   test_d['Name'] = "test_f process"
   test_d['Number'] = 1
   for j in range(0, 5):
     print "test_f", j
     test_d["ctr"] = j   ## update the dictionary
     time.sleep(1.0)
     
def test_f2(name):
    for j in range(0, 15):
       print "   test_f2", j
       time.sleep(0.5)

if __name__ == '__main__':
   manager = Manager()
   test_d = manager.dict()

   p = Process(target=test_f, args=(test_d,))
   p.start()
   p_pid = p.getPid()
   print "getpid", p_pid
   
   ##---  associate the pid and the process
   pid_dic = {}
   pid_dic[p_pid] = p

   p2 = Process(target=test_f2, args=('P2',))
   p2.start()
   p2_pid = p2.getPid()

   ##---  add the second process to the dictionary  
   pid_dic[p2_pid] = p2

   ##---  sleep and terminate the first process
   time.sleep(3.0)
   print "\nterminate", p_pid
   pid_dic[p_pid].terminate()
   print "data from first process", test_d
   print "\nThe second process continues to run to conclusion"
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.