2009-10-22 8 views
10

Ryan Tomayko provocó una tormenta de fuego con this post sobre el uso de comandos de control de proceso de Unix.Usando métodos de control de proceso de Unix en Ruby

Deberíamos estar haciendo más de esto. Mucho más de esto. Estoy hablando de fork (2), execve (2), pipe (2), socketpair (2), select (2), kill (2), sigaction (2), y así sucesivamente. Estos son nuestros amigos Ellos quieren desesperadamente ayudarnos.

que tienen un poco de código (un clon de delayed_job DataMapper que creo que encajaría perfectamente con esto, pero no me queda claro sobre cómo tomar ventaja de los comandos que aparecen. ¿Alguna idea sobre cómo mejorar este código?

def start 
    say "*** Starting job worker #{@name}" 
    t = Thread.new do 
    loop do 
     delay = Update.work_off(self) 
     break if $exit 
     sleep delay 
     break if $exit 
    end 
    clear_locks 
    end 

    trap('TERM') { terminate_with t } 
    trap('INT') { terminate_with t } 

    trap('USR1') do 
    say "Wakeup Signal Caught" 
    t.run 
    end 
end 

Respuesta

3

Ahh sí ... los peligros de la "debemos hacer más de esto", sin explicar lo que cada uno de los haces y en qué circunstancias debería usar este recurso. Por algo así como delayed_job incluso se puede esté usando fork sin saber que está usando fork. Dicho esto, realmente no importa. Ryan estaba hablando de usar fork para servidores de prefabricación. delayed_job usaría fork para convertir un proceso en un daemon. Misma llamada al sistema, diferentes propósitos. Ejecutar delayed_job en primer plano (sin fork) vs en el fondo (con fork) dará lugar a una diferencia de rendimiento insignificante.

Sin embargo, si escribe un servidor que acepte conexiones concurrentes, ahora el consejo de Ryan es justo sobre el dinero.

  • fork: crea una copia del proceso original
  • execve: deja de ejecutar el archivo actual y comienza a ejecutar un nuevo archivo en el mismo proceso (muy útil en tareas rake)
  • pipe: crea una canalización (dos descriptores de archivos, uno para lectura, uno para escribir)
  • socketpair: como un tubo, pero para tomas
  • select: de espera a que uno o más de varios descriptores de fichero dejar que sean leídos y con un tiempo de espera
  • kill: se utiliza para enviar una señal a un proceso
  • sigaction: le permite cambiar lo que sucede cuando un proceso recibe una señal
+0

Así que, en lugar de crear un hilo (verde), podría usar fork (2) en su lugar y recuperar un PID. Esto mucho que he hecho. ¿Cómo trabajo con el bloque para trampa ('USR1') que despierta el hilo cuando el nuevo trabajo llega a la cola? ¿Cómo crearía más de un proceso y lograré que salgan de la cola de manera óptima? La magia parece estar en la tubería y seleccionar, pero no entiendo las complejidades. Puedo usar la gema daemon para crear un proceso daemon que use un tenedor debajo del capó. Quiero iniciar algunos procesos secundarios para ejecutar la cola. –

+0

Depende de qué significa "trabajo" en este contexto. Si "trabajo" es E/S, podría ser diferente y sí, 'seleccionar' es importante. Prefiero diseñar colas de trabajo de tal manera que el trabajo se pueda ejecutar en cualquier orden. Entonces, si la unidad de trabajo n. ° 1 se ejecuta al mismo tiempo que la unidad de trabajo n. ° 2, eso no es un problema. En cuanto a la gema daemons ... solía usarla, pero ahora uso 'fork' directamente o uso mi biblioteca ChainGang.Descubrí que los daemons escondían demasiadas cosas importantes, y que era innecesario por encima de algo que en realidad no es tan difícil. Tenga en cuenta que ChainGang es muy de calidad alfa. –

+0

Esencialmente, preocuparse por "sacar la fila de manera óptima" no tiene mucho sentido en la mayoría de los contextos. O bien está trabajando con E/S, en cuyo caso probablemente no esté utilizando una cola 'delayed_job', o esté ejecutando cosas como unidades de trabajo discretas, en cuyo caso' select' y 'pipe' no hacen ninguna sentido. De cualquier manera, la forma correcta de lidiar con una cola de trabajo es simplemente agarrar lo que esté arriba siempre que sea libre. Y si no hay nada allí, probablemente sea correcto bloquearlo hasta que lo haya. –

Cuestiones relacionadas