procesos multitarea libreria crear concurrentes con python sockets communication pipe interprocess

multitarea - procesos concurrentes python



comunicación entre procesos en python (6)

Consulte una biblioteca / servidor multiplataforma llamado RabbitMQ. Puede ser demasiado pesado para la comunicación de dos procesos, pero si necesita una comunicación multiproceso o de código múltiple (con varios medios diferentes, por ejemplo, de uno a muchos, colas, etc.), es una buena opción.

Requisitos:

$ pip install pika $ pip install bson # for sending binary content $ sudo apt-get rabbitmq-server # ubuntu, see rabbitmq installation instructions for other platforms

Editor (envía datos):

import pika, time, bson, os connection = pika.BlockingConnection(pika.ConnectionParameters(''localhost'')) channel = connection.channel() channel.exchange_declare(exchange=''logs'', type=''fanout'') i = 0 while True: data = {''msg'': ''Hello %s'' % i, b''data'': os.urandom(2), ''some'': bytes(bytearray(b''/x00/x0F/x98/x24''))} channel.basic_publish(exchange=''logs'', routing_key='''', body=bson.dumps(data)) print("Sent", data) i = i + 1 time.sleep(1) connection.close()

Suscriptor (recibe datos, puede ser múltiple):

import pika, bson connection = pika.BlockingConnection(pika.ConnectionParameters(host=''localhost'')) channel = connection.channel() channel.exchange_declare(exchange=''logs'', type=''fanout'') result = channel.queue_declare(exclusive=True) queue_name = result.method.queue channel.queue_bind(exchange=''logs'', queue=queue_name) def callback(ch, method, properties, body): data = bson.loads(body) print("Received", data) channel.basic_consume(callback, queue=queue_name, no_ack=True) channel.start_consuming()

Ejemplos basados ​​en https://www.rabbitmq.com/tutorials/tutorial-two-python.html

¿Cuál es una forma limpia y elegante de hacer comunicación entre procesos entre dos procesos Python diferentes? Actualmente uso canalizaciones con nombre en el sistema operativo, pero se siente un poco hacky. Reescribí mis cosas con los servicios dbus , lo que funcionó, pero parece que al ejecutar el código de forma remota a través de una sesión SSH ahora intenta inicializar X11, lo que parece completamente innecesario para las cosas que quiero hacer (no están relacionadas con la GUI). Entonces quizás dbus sea ​​un poco pesado. Estaba a punto de rediseñar usando sockets, pero parece bastante bajo, así que pensé que podría haber un módulo de nivel superior que pudiera importar y usar del que simplemente no sé el nombre, y pensé que debería preguntarle SO primero..

Mi requisito es poder ejecutar python foo.py y hacer que ese proceso lo haga, como un daemon, y poder enviar mensajes con python foo.py --bar . La última llamada debería simplemente enviar un mensaje al proceso existente y terminar, posiblemente con un código de retorno 0 para el éxito u otro para la falla (por lo que se requerirá alguna comunicación bidireccional).


Desde mi experiencia, rpyc es, de lejos, la manera más simple y elegante de hacerlo.

(Sé que esta es una vieja pregunta, pero acabo de tropezar con ella ..)


La biblioteca de multiprocessing proporciona oyentes y clientes que envuelven sockets y le permiten pasar objetos arbitrarios de python.

Su servidor podría escuchar recibir objetos de Python:

from multiprocessing.connection import Listener address = (''localhost'', 6000) # family is deduced to be ''AF_INET'' listener = Listener(address, authkey=''secret password'') conn = listener.accept() print ''connection accepted from'', listener.last_accepted while True: msg = conn.recv() # do something with msg if msg == ''close'': conn.close() break listener.close()

Su cliente podría enviar comandos como objetos:

from multiprocessing.connection import Client address = (''localhost'', 6000) conn = Client(address, authkey=''secret password'') conn.send(''close'') # can also send arbitrary objects: # conn.send([''a'', 2.5, None, int, sum]) conn.close()


Nah, zeromq es el camino a seguir. Delicioso, ¿verdad?

import argparse import zmq parser = argparse.ArgumentParser(description=''zeromq server/client'') parser.add_argument(''--bar'') args = parser.parse_args() if args.bar: # client context = zmq.Context() socket = context.socket(zmq.REQ) socket.connect(''tcp://127.0.0.1:5555'') socket.send(args.bar) msg = socket.recv() print msg else: # server context = zmq.Context() socket = context.socket(zmq.REP) socket.bind(''tcp://127.0.0.1:5555'') while True: msg = socket.recv() if msg == ''zeromq'': socket.send(''ah ha!'') else: socket.send(''...nah'')


Yo usaría enchufes, pero usaría Twisted para darle algo de abstracción y facilitar las cosas. Su ejemplo Simple Echo Client / Server es un buen lugar para comenzar.

Simplemente tendría que combinar los archivos y crear instancias y ejecutar el cliente o servidor dependiendo de los argumentos pasados.


Yo usaría enchufes; La comunicación local se optimizó en gran medida, por lo que no debería tener problemas de rendimiento y le da la capacidad de distribuir su aplicación a diferentes nodos físicos si surgieran las necesidades.

Con respecto al enfoque de "bajo nivel", tienes razón. Pero siempre puedes usar un contenedor de nivel superior dependiendo de tus necesidades. XMLRPC podría ser un buen candidato, pero tal vez sea excesivo para la tarea que intenta realizar.

Twisted ofrece algunas buenas implementaciones simples de protocolo, como LineReceiver (para mensajes simples basados ​​en líneas) o el más elegante AMP (que, por cierto, estaba estandarizado e implementado en diferentes idiomas ).