import subprocess
def my_function(x):
return x + 100
output = subprocess.Popen(my_function, 1) #I would like to pass the function object and its arguments
print output
#desired output: 101
I have only found documentation on opening subprocesses using separate scripts. Does anyone know how to pass function objects or even an easy way to pass function code?
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
I think you’re looking for something more like the multiprocessing module:
http://docs.python.org/library/multiprocessing.html#the-process-class
The subprocess module is for spawning processes and doing things with their input/output – not for running functions.
Here is a multiprocessing version of your code:
from multiprocessing import Process, Queue
# must be a global function
def my_function(q, x):
q.put(x + 100)
if __name__ == '__main__':
queue = Queue()
p = Process(target=my_function, args=(queue, 1))
p.start()
p.join() # this blocks until the process terminates
result = queue.get()
print result
Method 2
You can use the standard Unix fork system call, as os.fork(). fork() will create a new process, with the same script running. In the new process, it will return 0, while in the old process it will return the process ID of the new process.
child_pid = os.fork() if child_pid == 0: print "New proc" else: print "Old proc"
For a higher level library, that provides multiprocessing support that provides a portable abstraction for using multiple processes, there’s the multiprocessing module. There’s an article on IBM DeveloperWorks, Multiprocessing with Python, with a brief introduction to both techniques.
Method 3
Brian McKenna’s above post about multiprocessing is really helpful, but if you wanted to go down the threaded route (opposed to process-based), this example will get you started:
import threading
import time
def blocker():
while True:
print "Oh, sorry, am I in the way?"
time.sleep(1)
t = threading.Thread(name='child procs', target=blocker)
t.start()
# Prove that we passed through the blocking call
print "No, that's okay"
You can also use the setDaemon(True) feature to background the thread immediately.
Method 4
You can use concurrent.futures.ProcessPoolExecutor, which not only propagates the return value, but also any exceptions:
import concurrent.futures
# must be a global function
def my_function(x):
if x < 0:
raise ValueError
return x + 100
with concurrent.futures.ProcessPoolExecutor() as executor:
f = executor.submit(my_function, 1)
ret = f.result() # will rethrow any exceptions
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0