2011-06-04 8 views
7

Recientemente se planteó una pregunta con respecto a algún código de Python que intenta facilitar la computación distribuida mediante el uso de procesos encurtidos. Aparentemente, esa funcionalidad ha sido históricamente posible, pero por razones de seguridad, la misma funcionalidad está deshabilitada. En el segundo intento de transmitir un objeto de función a través de un socket, solo se transmitió la referencia. Corrígeme si me equivoco, pero no creo que este problema esté relacionado con el enlace tardío de Python. Dada la presunción de que los objetos de procesos y subprocesos no se pueden escanear, ¿hay alguna forma de transmitir un objeto invocable? Nos gustaría evitar transmitir código fuente comprimido para cada trabajo, ya que eso probablemente haría que todo el intento no tenga sentido. Solo la biblioteca principal de Python se puede usar por razones de portabilidad.Necesitamos eliminar cualquier tipo de calificable

+2

Siempre que se pregunte "X no está permitido * por razones de seguridad *; ¿cómo puedo solucionar esto?", Debe estar preparado con una explicación ** detallada ** de por qué ** necesita * * para evitarlo. La seguridad es un asunto serio. –

+0

@Karl, ese es un punto excelente. Establecer que una solución alternativa es una necesidad sería una exageración. Cometí el error de incluso sugerir la salida más fácil. Lo seguiré haciendo, comenzando con la sugerencia de Artur. – motoku

+1

Si un código es python puro, entonces es tan portátil como la biblioteca principal de python. Tengo un serializador de python puro que puede extraer cualquier llamativo ... y se utiliza como la columna vertebral de una biblioteca de computación distribuida y paralela pura de python. Es portátil ... y puede construir redes de mapas jerárquicos paralelos y distribuidos en paralelo. Lo que quiero decir es que si un paquete es python puro, no debe excluirlo; solo debe instalarlo en su área de usuario en el clúster distribuido si aún no está instalado. Vea el paquete 'eneldo ', que es básicamente una colección de llamadas pickle' copy_reg'. –

Respuesta

6

Se podría reunir el código de bytes y el decapado de las otras cosas de función:

import marshal 
import pickle 

marshaled_bytecode = marshal.dumps(your_function.func_code) 
# In this process, other function things are lost, so they have to be sent separated. 
pickled_name = pickle.dumps(your_function.func_name) 
pickled_arguments = pickle.dumps(your_function.func_defaults) 
pickled_closure = pickle.dumps(your_function.func_closure) 
# Send the marshaled bytecode and the other function things through a socket (they are byte strings). 
send_through_a_socket((marshaled_bytecode, pickled_name, pickled_arguments, pickled_closure)) 

en otro programa Python:

import marshal 
import pickle 
import types 

# Receive the marshaled bytecode and the other function things. 
marshaled_bytecode, pickled_name, pickled_arguments, pickled_closure = receive_from_a_socket() 
your_function = types.FunctionType(marshal.loads(marshaled_bytecode), globals(), pickle.loads(pickled_name), pickle.loads(pickled_arguments), pickle.loads(pickled_closure)) 

y cualquier referencia a variables globales dentro de la función tendría que ser recreada en el script que recibe la función.

En Python 3, los atributos de función utilizados son __code__, __name__, __defaults__ y __closure__.

Tenga en cuenta que send_through_a_socket y receive_from_a_socket no existen, y debe reemplazarlos por el código real que transmite datos a través de sockets.

+0

[Que] (http://stackoverflow.com/questions/6212326/python-distributed-computing-with-error-edited) _seems_ funciona parcialmente. – motoku

+0

Gracias. Ver otro hilo. – motoku

Cuestiones relacionadas