Question

I would like to create a shell which will control a separate process that I created with the multiprocessing module. Possible? How?

EDIT:

I have already achieved a way to send commands to the secondary process: I created a code.InteractiveConsole in that process, and attached it to an input queue and an output queue, so I can command the console from my main process. But I want it in a shell, probably a wx.py.shell.Shell, so a user of the program could use it.

Was it helpful?

Solution

  1. First create the shell
  2. Decouple the shell from your app by making its locals empty
  3. Create your code string
  4. Compile the code string and get a code object
  5. Execute the code object in the shell
    from wx.py.shell import Shell

    frm = wx.Frame(None)
    sh = Shell(frm)
    frm.Show()    
    sh.interp.locals = {}
    codeStr = """
    from multiprocessing import Process, Queue

    def f(q):
        q.put([42, None, 'hello'])

    q = Queue()   
    p = Process(target=f, args=(q,))
    p.start()
    print q.get()    # prints "[42, None, 'hello']"
    p.join()
    """

    code = compile(codeStr, '', 'exec')
    sh.interp.runcode(code)

Note: The codeStr I stole from the first poster may not work here due to some pickling issues. But the point is you can execute your own codeStr remotely in a shell.

OTHER TIPS

You can create a Queue which you pass to the separate process. From the Python Docs:

from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, 'hello'])

if __name__ == '__main__':
    q = Queue()
    p = Process(target=f, args=(q,))
    p.start()
    print q.get()    # prints "[42, None, 'hello']"
    p.join()

EXAMPLE: In the wx.py.shell.Shell Docs the constructur parameters are given as

__init__(self, parent, id, pos, size, style, introText, locals, 
         InterpClass, startupScript, execStartupScript, *args, **kwds) 

I have not tried it, but locals might be a dictionary of local variables, which you can pass to the shell. So, I would try the following:

def f(cmd_queue):
    shell = wx.py.shell.Shell(parent, id, pos, size, style, introText, locals(),
                              ...)

q = Queue()
p = Process(target=f, args=(q,))
p.start()

Inside the shell, you should then be able to put your commands into cmd_queue which have then to be read in the parent process to be executed.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top