【问题标题】:Background process in PythonPython中的后台进程
【发布时间】:2011-11-02 17:17:26
【问题描述】:

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

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'

这就是我向进程发送数据的方式: 第一次测试运行正常:

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

后来由于某种原因raw_input() 得到一个 EOF 并且进程退出。设置进程间通信的正确方法是什么?

【问题讨论】:

    标签: python subprocess multiprocessing popen


    【解决方案1】:

    我喜欢为此使用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()
    

    【讨论】:

    • 在 MQ comparison article 中,我读到 Python zeromq 扩展已损坏的说法。这些问题解决了吗?
    • 还有一点需要注意:pyzmq 也有一些不错的方法来发送 json 或 pickled python 对象,你也可以使用client.send_json({'name': 'name', 'args': list()})client.send_pyobj()
    • 谢谢,看来这就是我需要的东西。
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      我相信communicate() 会关闭标准输入,这会给你的进程一个EOF。

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

      【讨论】:

        【解决方案4】:

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

        我喜欢使用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('pexpect@sourceforge.net')
         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()
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-01-30
          • 2020-03-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多