Reputation: 65
When performing multiprocessing in python using the Process call, I would like to immediately print a completion statement after completion of each process from the parent process rather than in the child worker function. I am doing this in a Tk GUI, so the sys.stdout is redirected (see simple example version below). If I print inside the worker function (printLetters - uncomment out "#print letter") I get the error: "The process has forked and you cannot use this CoreFoundation functionality safely. You MUST exec()."
If someone can suggest a way to fix either of these two issues (identifying when the queue has been updated from the parent process OR a way to print inside a process with sys.stdout redirected), it would be greatly appreciated.
Thanks...
import Tkinter
from Tkinter import *
import multiprocessing
import time
from multiprocessing import Process, Queue
class StringVarFile:
def __init__(self,stringVar,window):
self.__newline = 0
self.__stringvar = stringVar
self.__window = window
def write(self,s):
new = self.__stringvar.get()
for c in s:
if self.__newline:
new = ""; self.__newline = 0
new = new+c
self.set(new)
def set(self,s):
self.__stringvar.set(s); self.__window.update()
def get(self):
return self.__stringvar.get()
def flush(self): pass
def executeSomething(letters):
procs=list()
queue = Queue()
print 'Begining letter printing...'
for letter in letters:
p = Process(target=printLetters, args=(queue,letter))
procs.append(p)
p.start()
for p in procs:
p.join()
print 'Finished printing letters'
def printLetters(queue,letter):
time.sleep(2)
#print letter
queue.put(letter)
if __name__ == '__main__':
root = Tk()
statusVar = StringVar() ### Class method for Tkinter. Description: "Value holder for strings variables."
letters = ['a','b','c','d']
Label(root,width=50,height=10,textvariable=statusVar).pack()
sys.stdout = StringVarFile(statusVar,root)
root.after(100, executeSomething(letters))
root.mainloop()
Upvotes: 0
Views: 844
Reputation: 10985
Do you just want to print to the GUI? If so, inside executeSomething()
between starting and joining the processes, why not just iterate over queue results? Like this:
for letter in letters:
print queue.get()
Upvotes: 1