I found a solution which implements a modified output Queue on top of Roger
Stuckey’s Simpler wxPython Multiprocessing
Example framework. The pre below
is even Simpler than his; it could also be cleaned out a little. Hope it helps
someone else. I still have a nagging feeling that there should be a more
straightforward way of doing this though.
import getopt, math, random, sys, time, types, wx, subprocessfrom multiprocessing import Process, Queue, cpu_count, current_process, freeze_supportfrom Queue import Emptyclass Myframe(wx.frame): def __init__(self, parent, id, title): wx.frame.__init__(self, parent, id, title, wx.Point(700, 500), wx.Size(300, 200)) self.panel = wx.Panel(self, wx.ID_ANY) #widgets self.start_bt = wx.Button(self.panel, wx.ID_ANY, "Start") self.Bind(wx.EVT_BUTTON, self.OnButton, self.start_bt) self.output_tc = wx.TextCtrl(self.panel, wx.ID_ANY, style=wx.TE_MULTILINE|wx.TE_READONLY) # sizer self.sizer = wx.GridBagSizer(5, 5) self.sizer.Add(self.start_bt, (0, 0), flag=wx.ALIGN_CENTER|wx.LEFT|wx.TOP|wx.RIGHT, border=5) self.sizer.Add(self.output_tc, (1, 0), flag=wx.EXPAND|wx.LEFT|wx.RIGHT|wx.BOTTOM, border=5) self.sizer.AddGrowableCol(0) self.sizer.AddGrowableRow(1) self.panel.SetSizer(self.sizer) # Set some program flags self.keepgoing = True self.i = 0 self.j = 0 def onButton(self, event): self.start_bt.Enable(False) self.numtasks = 4 self.numproc = 2 #self.numproc = cpu_count() self.output_tc.AppendText('Number of processes = %dn' % self.numproc) # Create the queues self.taskQueue = Queue() self.outputQueue = Queue() # Create the task list self.Tasks = range(self.numtasks) # The worker processes... for n in range(self.numproc): process = Process(target=self.worker, args=(self.taskQueue, self.outputQueue)) process.start() # Start processing tasks self.processTasks(self.update) if (self.keepgoing): self.start_bt.Enable(True) def processTasks(self, resfunc=None): self.keepgoing = True # Submit first set of tasks numprocstart = min(self.numproc, self.numtasks) for self.i in range(numprocstart): self.taskQueue.put(self.Tasks[self.i]) self.j = -1 # done queue index self.i = numprocstart - 1 # task queue index while (self.j < self.i): # Get and print results self.j += 1 output = None while output != 'STOP!': try: output = self.outputQueue.get() if output != 'STOP!': resfunc(output) except Empty: break if ((self.keepgoing) and (self.i + 1 < self.numtasks)): # Submit another task self.i += 1 self.taskQueue.put(self.Tasks[self.i]) def update(self, output): self.output_tc.AppendText('%s PID=%d Task=%d : %sn' % output) wx.YieldIfNeeded() def worker(self, inputq, outputq): while True: try: tasknum = inputq.get() print '## Now Running: ', tasknum #this goes to terminal/console. Add it to outputq if you'd like it on the TextCtrl. command = ['./script.sh'] p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) while True: r = p.stdout.readline() if not r: outputq.put('STOP!') break outputq.put(( current_process().name, current_process().pid, tasknum, r.rstrip())) except Empty: break # The worker must not require any existing object for execution! worker = classmethod(worker)class MyApp(wx.App): def onInit(self): self.frame = Myframe(None, -1, 'stdout to GUI using multiprocessing') self.frame.Show(True) self.frame.Center() return Trueif __name__ == '__main__': freeze_support() app = MyApp(0) app.MainLoop()
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)