2011-08-24 83 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()