2011-08-24 49 views
4

我需要创建一个后台进程,等待传入的命令并执行它们。下面的代码:Python中的后台进程

instance_tuple.popen = subprocess.Popen(['python',\ 
            os.path.join(config['scripts_dir'],\ 
            'instance_script.py')],\ 
            stdin = subprocess.PIPE,\ 
            stdout = subprocess.PIPE) 

处理功能代码:

if __name__ == '__main__': 
    config = dict() 
    is_config_valid = False 
    print 'Hello from instance process' 
    while True: 
     cmd_str = raw_input() 
     if (cmd_str.strip() != ''): 
      print 'received %s' % cmd_str 
      command = json.loads(cmd_str) 
     print 'received command: %s' % str(command) 
     sys.stdout.flush() 
     if command['name'] == 'set_variable': 
      name = command['args'][0] 
      value = command['args'][1] 
      config[name] = value 
      is_config_valid = validate_instance_dict(config)    
     elif is_config_valid: 
      if (command['name'] == 'init_model'): 
       config['instance'].init_model() 
      elif (command['name'] == 'get_tree'): 
       tree = config['instance'].get_fidesys_tree(command['args']) 
       result = CommandResult(command.name, tree) 
    print 'process exit' 

这就是我如何将数据发送到过程: 月1日试运行工作正常:

(input, errors) = instance_tuple.popen \ 
        .communicate(json.dumps({'name': 'name', 'args': list()})) 

后来由于某种原因raw_input()获得EOF并且该过程退出。什么是建立进程间通信的正确方法?

回答

5

我喜欢为此使用zeromq。我使用zmq.PULL套接字设置了一个服务器,它侦听使用zmq.PUSH套接字发送消息的客户端。真正易于使用:

import zmq 

def client(msg) 
    context = zmq.Context() 
    client = context.socket(zmq.PUSH) 
    client.connect('tcp://127.0.0.1:9999') 
    client.send(msg) 

def server(): 
    context = zmq.Context() 
    server = context.socket(zmq.PULL) 
    server.bind('tcp://127.0.0.1:9999') 

    while True: 
     msg = server.recv() 
     ..do something with each message 

if __name__ == '__main__': server() 
+0

谢谢,我会考虑这样做。 –

+0

在MQ [比较文章](http://wiki.secondlife.com/wiki/Message_Queue_Evaluation_Notes)中,我读到了Python zeromq扩展被破坏的说法。这些问题是否解决? –

+0

另一件需要注意的事情是:'pyzmq'也有一些发送json或pickled python对象的好方法,你也可以'client.send_json({'name':'name','args':list()} )'或'client.send_pyobj()'。 – zeekay

0

,如果你使用的 “sys.stdin.readline()” 的raw_input而不是会发生什么?

0

我相信沟通()关闭stdin,它给你的过程一个EOF。

如果您想多次交谈,请使用popen.stdin.write(...)。

0

子流程模块让你这样做,但你不能使用通信功能。

我喜欢使用pexpect模块。这很容易!
下面的例子,其中一个FTP连接创建和Python脚本创建的过程交互:

import pexpect 
import sys 

child = pexpect.spawn('ftp ftp.openbsd.org') 
child.expect('name .*: ') 
child.sendline('anonymous') 
child.expect('(password') 
child.sendline('[email protected]') 
child.expect('ftp> ') 
child.sendline('cd /pub/OpenBSD/3.7/packages/i386') 
... 
if child.isalive(): 
    child.sendline('bye') # Try to ask ftp child to exit. 
    child.close()