Tengo un programa posiblemente de larga ejecución que actualmente tiene 4 procesos, pero podría configurarse para tener más. Investigué logging from multiple processes usando python's logging
y estoy usando el enfoque SocketHandler discutido here. Nunca tuve problemas para tener un solo registrador (sin sockets), pero por lo que leí me dijeron que fallaría eventualmente e inesperadamente. Por lo que yo entiendo, es desconocido lo que sucederá cuando trates de escribir en el mismo archivo al mismo tiempo. Mi código hace esencialmente lo siguiente:Registro Python desde procesos múltiples
import logging
log = logging.getLogger(__name__)
def monitor(...):
# Spawn child processes with os.fork()
# os.wait() and act accordingly
def main():
log_server_pid = os.fork()
if log_server_pid == 0:
# Create a LogRecordSocketServer (daemon)
...
sys.exit(0)
# Add SocketHandler to root logger
...
monitor(<configuration stuff>)
if __name__ == "__main__":
main()
Así que mis preguntas son: ¿Es necesario crear un nuevo objeto log
después de cada os.fork()
? ¿Qué ocurre con el objeto global log
existente?
Al hacer las cosas como soy, ¿estoy repasando el problema que trato de evitar (varios archivos/sockets abiertos)? ¿Fallará esto y por qué fallará (me gustaría poder decir si las implementaciones similares futuras fallarán)?
Además, ¿de qué manera falla el método "normal" (una expresión log=
) de iniciar sesión en un archivo de múltiples procesos? ¿Aumenta un IOError/OSError? ¿O simplemente no escribe completamente los datos en el archivo?
Si alguien pudiera proporcionar una respuesta o enlaces para ayudarme, sería genial. Gracias.
FYI: estoy probando en Mac OS X Lion y el código probablemente terminará ejecuta en una máquina virtual CentOS 6 en una máquina Windows (si lo que importa). Cualquier solución que use no necesita funcionar en Windows, pero debería funcionar en un sistema basado en Unix.
ACTUALIZACIÓN: Esta pregunta ha comenzado a alejarse de la tala comportamiento específico y es más en el ámbito de lo que hace Linux con descriptores de archivos durante horquillas. Saqué uno de mis libros de texto universitarios y parece que si abre un archivo en el modo de adición de dos procesos (no antes de un tenedor), ambos podrán escribir en el archivo correctamente, siempre que su escritura no exceda el búfer real del kernel (aunque es posible que haya que usar el buffer de línea, aún no estoy seguro de eso). Esto crea 2 entradas de tabla de archivos y una entrada de tabla v-node. No se supone que abrir un archivo y bifurcar funcione, pero parece que siempre y cuando no exceda el búfer del núcleo como antes (lo he hecho en un programa anterior).
Así que supongo que, si desea un registro multiproceso independiente de la plataforma, utilice conectores y cree un nuevo SocketHandler después de cada horquilla para que sea seguro como sugiere Vinay a continuación (esto debería funcionar en todas partes). Para mí, dado que tengo un fuerte control sobre el sistema operativo en el que se está ejecutando mi software, creo que voy a ir con un objeto global log
con un FileHandler (se abre en el modo de adición y la línea está almacenada en la mayoría de los sistemas operativos). La documentación para open
dice "Un buffer negativo significa usar el sistema predeterminado, que generalmente es un buffer de línea para dispositivos tty y está totalmente almacenado en el búfer para otros archivos. Si se omite, se usa el sistema predeterminado". o podría simplemente crear mi propia secuencia de registro para garantizar el almacenamiento en línea de la memoria. Y sólo para que quede claro, yo estoy bien con:
# Process A
a_file.write("A\n")
a_file.write("A\n")
# Process B
a_file.write("B\n")
producir ...
A\n
B\n
A\n
con tal de que no produce ...
AB\n
\n
A\n
Vinay (o cualquier otro), lo equivocado soy yo? Házmelo saber. Gracias por más claridad/seguridad que puede proporcionar.
Los hilos y los bloqueos son útiles para cosas como esta ... –
Necesito procesos separados ya que los niños se están comunicando con dispositivos externos que deberían ser lo más "rápidos" posible. – daveydave400
He actualizado mi respuesta. –