2010-07-26 12 views
5

Tengo un script PHP independiente, y manejaría una señal enviada desde el sistema operativo Windows para hacer un apagado elegante cuando se emite una "señal de muerte".Manejo de señales en Windows

¿Cómo puedo hacer eso en Windows?

Respuesta

3

Si bien la única otra respuesta aquí es sucinta y precisa, carece de detalles sobre por qué no hay señal de soporte en Windows.

En primer lugar, las señales son una forma bastante limitada y obsoleta de comunicarse con un proceso. Hay muchas formas más ricas de informar un proceso que necesita dejar lo que está haciendo y hacer otra cosa. Incluso en las plataformas POSIX, los manejadores de señal están diseñados para ser MUY livianos: el código en los manejadores de señal debe estar listo/capaz de manejar múltiples señales que llegan al mismo tiempo.

PHP permite manipuladores de señal a través de pcntl_signal() con un número significativo de advertencias. Antes de que puedan ser utilizados, el código tiene que ajustar el número de "tics" que pasan antes de que PHP pase una señal que llegó a un controlador. Un tic es la cantidad de instrucciones que Zend (el núcleo de PHP) ejecutará antes de verificar el estado del manejador de señal y ejecutar las devoluciones de llamada necesarias. Básicamente es un bucle ocupado dentro del ciclo principal de ejecución. Como tal, ajustar las garrapatas ralentizará drásticamente el proceso si se sigue la recomendación por tick de 1. Los comentarios sobre la función sugieren que un valor de tilde de 100 es suficiente en la mayoría de los sistemas. La forma más fácil de entender cómo funciona el controlador es que hay un controlador de señal real detrás de escena que recopila información de señal, que PHP ocasionalmente consulta para ver si se llamó al manejador, qué señal se envió, etc. - si es así, entonces el la información se transfiere a una devolución de llamada en el dominio del usuario (es decir, su código). No es un manejo de señal real y nunca será debido a los peligros y dificultades que presenta el manejo de señal real.

El segundo problema es que, incluso con el soporte del manejador de pseudo-señal que proporciona pcntl_signal(), PHP puede perder información sobre las señales que se produjeron. Si ocurre el escenario de múltiples señales, no se notificará al script que alguna señal sucedió varias veces. Cuanto mayor sea el valor de la marca, es más probable que esto suceda, especialmente en un sistema ocupado.

Windows, en su mayor parte, realmente no usa señales. Existe la función SetConsoleCtrlHandler() que existe para capturar Ctrl + C y Ctrl + Break y es más o menos equivalente a SIGINT. Las desventajas son que tiene que haber una consola conectada al proceso para que funcione y otros procesos no pueden enviarla. La función TerminateProcess() es equivalente a SIGKILL, que no se puede bloquear/manejar en otros sistemas operativos y la señal SIGKILL no llega realmente al proceso objetivo. Aparte de esas dos funciones/señales, hay muy poco en común. En definitiva, Windows es una bestia muy diferente bajo el capó.

La única razón para mirar señales es para algún tipo de proceso PHP de larga duración, una tarea que todos parecen decir para la que el lenguaje no es adecuado (estoy completamente en desacuerdo, pero esa es una discusión diferente). A medida que aprendí sobre las limitaciones del soporte de señales en PHP incluso en los sistemas operativos POSIX, decidí que realmente no eran la respuesta a mi situación. La solución correcta es ignorar las señales por completo. Para SIGINT, los guiones de la línea de comandos se deben escribir para manejar el escenario de terminación prematura, es decir, deben ser idempotentes. En el mundo de PHP, las señales son en gran medida irrelevantes ya que existen otras soluciones más flexibles y ricas que incluyen mutexes/eventos con nombre, sockets, archivos, named pipes, memoria compartida, Service Manager, etc.

4

PHP no admite la gestión de señales en Windows. Lo siento.

+1

En particular, la única manera PHP puede manejar señales con la función [pcntl_signal] (http://php.net/manual/en/function.pcntl-signal.php), parte de la [extensión pcntl] (http://www.php.net /manual/en/intro.pcntl.php), que no funciona en Windows. – Charles