Escriba un programa que se inicie nuevamente cuando finalice.
No debe haber más de una instancia del programa ejecutándose al mismo tiempo. Ni siquiera por el más mínimo momento.
Puede ignorar cualquier instancia que el usuario inicie manualmente durante su ciclo. Pero su código no debería hacerlo en su ciclo de reinicio.
El programa puede comenzar después de cualquier cantidad de tiempo, siempre y cuando se garantice que se inicia nuevamente.
La única forma de detener el ciclo es matar el proceso.
Su solución no debe implicar el reinicio del entorno (en el que se ejecuta el programa, incluye SO, máquina, VM, shell, etc.). Solo su programa puede reiniciar.
popularity-contest
microbiano
fuente
fuente
exec
hace en Linux?shutdown -r -t 0 -f
".Respuestas:
Bash script, 3 caracteres (el más corto, posiblemente el más elegante, aunque ciertamente controvertido)
Simplemente coloca una nueva instancia de sí misma en segundo plano (nuevo proceso), luego se cierra. La nueva instancia probablemente permanecerá en la cola de ejecución del planificador hasta que se complete la instancia anterior.
Advertencia: esto es difícil
kill
, ya que el PID cambia continuamente. Cambiar el nombre temporalmente del archivo de script es probablemente la forma más sencilla de romper el ciclo.Se supone un sistema de un solo núcleo. Por supuesto, esto no es realista con Linux en hardware moderno de metal desnudo, pero es fácilmente configurable cuando se ejecuta en una VM. Probablemente podríamos lograr un truco similar usando
taskset
, pero eso reduciría el impacto de la solución 3-char.Esta respuesta dobla las reglas un poco porque aplica un significado específico de "correr". Habrá momentos en los que el nuevo proceso ha sido
fork()
editado y el proceso anterior todavía está vivo, es decir, es posible observar más de un PID. Sin embargo, el nuevo proceso se colocará en la cola de ejecución del planificador de Linux para esperar los ciclos de la CPU, mientras que el proceso existente continuará ejecutándose. En este punto, todo lo que debe hacer el proceso existente es hacerlo porbash
sí mismoexit()
. Esto lleva una cantidad de tiempo finita, aunque estoy bastante seguro de que se hará mucho antes de que se realice el tiempo actual / quantum del planificador. La evidencia de respaldo es el hecho de que sebash
inicia y se apaga en 2 ms en mi VM:La evidencia adicional de que el nuevo proceso en realidad no se ejecuta hasta que se realiza el proceso anterior se puede ver en la
strace
salida:En la salida, vemos que el proceso original tiene PID 6929. Podemos ver la
fork()
llamada (en realidadclone()
), que devuelve un nuevo PID de 6930. En este punto, hay 2 PID, pero solo 6929 se está ejecutando actualmente:Llena
strace
de salida aquí.Podemos ver que 6930 no emite ninguna llamada del sistema hasta 6929 está completamente hecho. Es razonable suponer que esto no significa 6930 publiquen hasta 6929 está hecho. La
perf
utilidad sería la mejor manera de demostrar esto.fuente
top
no es la herramienta adecuada para usar aquí. Sin embargo, veo quetime bash -c :
solo toma 2 ms en mi VM de Ubuntu, por lo que no creo que sea irrazonable esperarbash
completar su apagado antes de que se complete su programación cuántica.Solución 1
PHP, 32 caracteres
Envía el encabezado y luego se detiene. Después de 3 segundos, la página se vuelve a cargar.
archivo a.php
Esto se puede detener al finalizar la ejecución de la página antes de que se envíen los encabezados, o simplemente matando el navegador.
Solución 2
PHP, 2 páginas
Vamos a considerar los dos archivos de dos programas diferentes. Los dos archivos se encuentran en la misma carpeta.
archivo a.php
archivo b.php
Terminar una de las páginas antes de que se envíen los encabezados termina el programa (matar el navegador también funciona).
Aquí está el mismo programa en
ASP.NET
archivo a.aspx
archivo b.aspx
fuente
sh
Esto funcionará en cualquier sistema compatible con Posix.
Para eliminarlo, elimine el archivo o úselo
atrm
.fuente
golpetazo
exec
reemplaza el shell sin crear un nuevo proceso. Esto asegura que no pueda haber una segunda instancia.fuente
~/.bash_profile
!$0
es-bash
cuando.bash_profile
se origina, por lo que eso solo daría como resultado un error de sintaxis.exec ${0##-}
en~/.bash_profile
obras :-)Programador de tareas de Windows (nativo)
C ++. Una pesadilla de programación COM. Cumple con todos los requisitos de desafío.
Compile con MSVC (o MinGW GCC si tiene todas las dependencias).
El programa se iniciará y registrará una tarea única con el programador de tareas de Windows para iniciarse 5 segundos después (Panel de control -> Herramientas administrativas -> Programador de tareas para ver, la tarea se llama "Reiniciar"). El programa hará una pausa de 5 segundos para darle la oportunidad de matarlo antes de que cree la tarea.
Requisitos de desafío:
Comienza de nuevo cuando termina. Sí. La tarea se programa justo antes de la salida del programa.
No más de una instancia del programa ejecutándose al mismo tiempo. Sí. El programa sale completamente y no se ejecuta durante 5 segundos. Lo inicia el planificador.
Puede ignorar cualquier instancia que el usuario inicie manualmente durante su ciclo. Sí, como efecto secundario del uso de un nombre de tarea constante.
Siempre y cuando esté garantizado que comience de nuevo. Sí, siempre que el Programador de tareas se esté ejecutando (está en una configuración estándar de Windows).
La única forma de detener el ciclo es matar el proceso. Sí, el proceso se puede eliminar durante la ventana de 5 segundos mientras se está ejecutando. El programa elimina la tarea antes de la demora de 5 segundos, eliminándola en este momento no dejará una tarea perdida en el programador.
Su solución no debe implicar reiniciar el entorno Sí.
Por cierto, si alguien alguna vez se preguntó por qué las aplicaciones de Windows solían ser tan inestables (antes del advenimiento de .NET y C #), esta es una de las razones. La cantidad de manejo de errores requerida (si la hubiera incluido), la administración de recursos y la verbosidad configuran situaciones muy propensas a errores si un programador es un poco flojo (el código anterior es extremadamente flojo).
Una alternativa mucho más fácil y más corta es invocar schtasks.exe. También he enviado una versión con eso en un script .BAT .
fuente
BBC BASIC: un homenaje a Snow Patrol
Emulator en bbcbasic.co.uk
Este es un poco diferente. Imprime un verso de la canción "Run" y toca un arpegio de los acordes para que puedas cantar. Se inspiró en el hecho de que el comando a ejecutar (y, por lo tanto, la última línea del programa) es, por supuesto, EJECUTAR.
Todas las variables se borran al inicio del programa, por lo que toma el color de la pantalla dejado por la iteración anterior para decidir qué verso imprimir a continuación.
OUTPUT (montaje de 4 capturas de pantalla diferentes)
fuente
HTML / JavaScript:
El código desencadena la destrucción de la página en la que se está ejecutando, luego la recreación de otra instancia de sí mismo cuando el navegador carga la página nuevamente.
AFAIK, la única salida es matar la pestaña en la que se ejecuta la página.
EDITAR: según la solicitud popular, un código HTML5 válido:
fuente
do
Este programa actúa como una gran cantidad de malware. Justo antes de que se cierre, crea un script de shell en el directorio / tmp. Se bifurca para iniciar el script de shell, lo que permite que el programa original se cierre y cancele el PID original. Después de un breve período de tiempo (2 segundos), el script de shell inicia un nuevo proceso con el programa. Por brevedad, la ubicación del programa está cableada como '/ tmp / neverend /'.
Solo hay un proceso 'interminable' ejecutándose a la vez. Cada nuevo proceso obtiene un nuevo PID. La forma más fácil de eliminar esto es eliminar el ejecutable. Si desea hacerlo más maligno, puede copiar tanto el ejecutable como el script para asegurarse de que haya varias copias en el programa en el disco en cualquier momento.
fuente
system()
si las reglas no cuentan un fork + exec/bin/sh
como un programa complementario.Perl
El script emite un comando del sistema para suicidarse y canaliza el resultado en otra instancia de sí mismo. El intérprete de Perl se usa para matar, por razones multiplataforma.
Detén la locura eliminando el guión.
fuente
Atari Basic de 8 bits
Tokeniza para:
Internamente está limpiando las estructuras internas, esencialmente borrando el programa, antes de ejecutarlo nuevamente desde la lista.
Esto es fundamentalmente diferente de:
Que se tokeniza para:
Este es un bucle infinito básico. Cuando los ejecutas, ves la diferencia en la velocidad (primero es más lento).
fuente
LIST
, no lo verías funcionando. ElegíLIST
porque tiene la entrada más cortaL.
. Me gusta la idea de poner eso en un búfer de teclado, ¡ciertamente es lo suficientemente corto!Return
? ¿Qué tan grande es el búfer del teclado? En el VIC-20 y C64, son diez bytes. Un programa que haga suficientes golpes para cargar el búfer del teclado probablemente no cabría en el búfer del teclado, pero he escrito programas que se modificarían a sí mismos al imprimir cambios en la pantalla seguidosRUN
, y rellenar algunasReturn
teclas. Tales cosas fueron especialmente útiles en el 64 ya que no tenía elIN
comando [IIRC] que tiene Atari para fusionar líneas en un programa.En un IBM Mainframe que ejecuta z / OS, ejecuta una utilidad que copia un conjunto de datos (archivo) a otro conjunto de datos (archivo). La entrada es la fuente del JCL (Job Control Language) que ha enviado para que se ejecute. La salida es el lector interno (INTRDR). También deberá asegurarse de que su sistema no permita la ejecución de múltiples nombres de trabajo idénticos. Es bueno usar una clase de trabajo que solo tiene un iniciador (lugar donde se puede ejecutar un TRABAJO en lote).
No hay PID involucrados (en z / OS), por lo que falla el conjunto de desafíos.
Detiene el proceso drenando y / o enjuagando. Si algo salió mal, drenando y / o enjuagando, jurando, pateando, intentando un arranque en caliente y finalmente con un arranque en frío o presionando el Botón Rojo Grande (y disparando al programador).
Puede que haya exagerado en el camino, pero no intentes esto en el trabajo ...
Ejemplo usando SORT. Los detalles en la tarjeta JOB dependen mucho del sitio. La política del sitio puede prohibir o impedir el uso de INTRDR. Se puede requerir una clase específica para usar el INTRDR. Si la política de su sitio prohíbe su uso , no lo use a menos que quiera llevar sus pertenencias a caminar en una caja de cartón.
Aunque hay buenos usos para el INTRDR, no lo use para este propósito . Ni siquiera tendrá la oportunidad de obtener su caja.
Otras utilidades están disponibles. Un programa rápido también sería fácil de hacer, solo leer un archivo, escribir un archivo.
Si desea que un ejemplo de esto salga mal, intente: http://ibmmainframes.com/viewtopic.php?p=282414#282414
La forma tradicional de copiar un conjunto de datos es usar la utilidad IBM IEBGENER, como alude ugoren en su comentario.
Sin embargo, en estos días, muchos sitios tendrán IEBGENER "alias" a ICEGENER. ICEGENER, si puede, usará DFSORT de IBM (o su rival SyncSort) para hacer una copia, porque los productos SORT están mucho más optimizados para IO que IEBGENER.
Solo estoy eliminando al intermediario usando SORT.
Si trabaja en un sitio de IBM Mainframe, conoce el formato de la tarjeta JOB que debe usar. La tarjeta de trabajo mínima es como he mostrado, sin el comentario. El comentario será importante, porque se supone que debes proporcionar información contable, por ejemplo. El nombre del trabajo probablemente tendrá un formato específico del sitio.
Algunos sitios prohíben o impiden el uso de INTRDR. Ten cuidado
Algunos sitios permiten ejecutar múltiples trabajos con el mismo nombre al mismo tiempo. Ten cuidado
Aunque a menos que sea un programador del sistema, no puede configurar una clase de este tipo, debe buscar una clase que permita solo un iniciador. Con eso, el proceso es bastante seguro, pero esté absolutamente seguro de que la clase funciona como se describe. Prueba. No con este trabajo.
Si usted es un programador del sistema, sabe que no debe hacer nada fuera de su competencia. 'Nuff dijo.
Con un trabajo con el mismo nombre permitido al mismo tiempo y un solo iniciador, esta será una secuencia constante de inicio / finalización del trabajo siguiente inicio / finalización del trabajo, hasta que complete el spool (otra cosa mala que hacer) con la salida de miles de trabajos (o quedarse sin números de trabajo). Mire una consola JES para mensajes de advertencia.
Básicamente, no hagas esto. Si lo hace, no lo haga en una máquina de producción.
Con un pequeño repaso, consideraré otra respuesta sobre cómo hacerlo en otro sistema operativo IBM Mainframe, z / VSE ... z / VSE usa JCL. z / OS usa JCL. Ellos son diferentes :-)
fuente
IEBGENER
entonces simplemente copiar.Python (72 bytes)
Podría hacerse más pequeño, supongo. Primero, codificando el nombre del archivo (en lugar de usar
__file__
). Pero aquí, puede poner este código en un archivo y ejecutarlo, sea cual sea su nombre :)fuente
&&
a&
.Programador de tareas de Windows (.BAT)
Script por lotes de Windows. Cumple con todos los requisitos de desafío.
Hasta donde puedo ver, esta es la única solución de Windows hasta ahora que cumple con todos los requisitos y no tiene dependencias no estándar (mi otra solución es similar pero requiere compilación).
El programa se comporta de manera similar a mi respuesta C ++ / COM .
El programa se iniciará y registrará una tarea única con el programador de tareas de Windows para iniciarse hasta 60 segundos más tarde (Panel de control -> Herramientas administrativas -> Programador de tareas para ver, la tarea se llama "Reiniciar"). El programa hará una pausa de 5 segundos para darle la oportunidad de matarlo antes de que cree la tarea.
Utiliza la interfaz de línea de comandos del Programador de tareas
schtasks.exe
. La aritmética en la secuencia de comandos consiste en calcular las compensaciones de tiempo manteniendo el tiempo válido y en formato HH: MM.Requisitos de desafío:
Comienza de nuevo cuando termina. Sí. La tarea se programa justo antes de la salida del programa.
No más de una instancia del programa ejecutándose al mismo tiempo. Sí. El programa sale completamente y no se ejecuta durante ~ 60 segundos. Lo inicia el planificador.
Puede ignorar cualquier instancia que el usuario inicie manualmente durante su ciclo. Sí, como efecto secundario del uso de un nombre de tarea constante.
Siempre y cuando esté garantizado que comience de nuevo. Sí, siempre que el Programador de tareas se esté ejecutando y schtasks.exe esté presente (ambos son verdaderos en las configuraciones predeterminadas de Windows).
La única forma de detener el ciclo es matar el proceso. Sí, el proceso se puede eliminar durante la ventana de 5 segundos mientras se está ejecutando. El programa elimina la tarea antes de la demora de 5 segundos, eliminándola en este momento no dejará una tarea perdida en el programador.
Su solución no debe implicar reiniciar el entorno Sí.
Nota: Debido a la interfaz de línea de comandos limitada, el tiempo de reinicio debe especificarse en minutos y la tarea no se reiniciará en las computadoras portátiles sin el adaptador de CA enchufado (lo siento).
fuente
Unix shell
Todavía no he visto muchas soluciones que dependan de un programa no relacionado para reiniciarlo. Pero esto es exactamente para lo que
at(1)
se hizo la utilidad:Es realmente difícil ver el programa en ejecución, ya que solo se ejecuta una vez por minuto y sale tan rápido. Afortunadamente, la
atq(1)
utilidad le mostrará que todavía está funcionando:Y
atrm(1)
te permitirá romper el ciclo:Puede reemplazar
1 minute
con1 hour
, o1 week
. O dele1461 days
un programa que se ejecute una vez cada 4 años.fuente
Potencia Shell
Estoy abusando (y posiblemente rompiendo) mi propia regla.
Se necesita una cantidad infinita de tiempo para reiniciarse.
Se puede matar al matar el proceso del host.
Sólo espera y mira ;)
fuente
while true; do sleep 1; done
quilifica, ¿no?Golpetazo
Guarde esto como repeat.sh en el directorio / y dele permiso de ejecución. Se puede eliminar eliminando el archivo
Esto funciona colocando una entrada en el crontab para ejecutarla 1 minuto después.
fuente
Visual Base 6 :)
Para ejecutar, cree un nuevo proyecto, agregue un módulo con este código, configure el objeto de inicio en "Sub Main", compile y luego ejecute el ejecutable.
Versión más legible:
fuente
HTML / JAVASCRIPT
ARCHIVO HTML a.html
fuente
Golpetazo
Más largo de lo que tiene que ser, pero estoy cansado y no me importa :)
Dijiste que tiene que reiniciarse cuando termina, no dijiste específicamente que tenía que hacerlo repetidamente o indefinidamente. Además, dijiste que nunca debería tener dos instancias ejecutándose a la vez ... nunca lo hará. ;)
Hay muchas maneras de hacer esto. Mi favorito personal sería hacer algo como enviar un paquete a algún lugar distante y luego (a través de cualquier número de métodos), hacer que la respuesta desencadene el proceso.
fuente
sleep
proceso se reinicia cuando finalizaAndroid: una alarma reiniciará la actividad después de 1 segundo
fuente
Entorno C + MPI
mpifork.c:
Debe tener OpenMPI o alguna otra implementación de MPI instalada.
Compilar conAhora que lo pienso, no hay razón para que tengas que usar mpicc - gcc o cualquier compilador que funcione. Solo tienes que tener mpirun.Para ejecutarlo, probablemente debería incluir el nombre completo de la ruta e incluir una lista de hosts. Por ejemplo, agregué algunas entradas en / etc / hosts que apuntaban a localhost, y lo ejecuté así:
El ejecutable debe estar en el mismo directorio en cualquier máquina en la que desee ejecutar esto.
Básicamente, esto toma una lista de hosts proporcionados en la línea de comando, selecciona uno de los hosts y lanza el ejecutable en el host de destino con los mismos argumentos. Si todo va perfectamente, mpirun se llamará una y otra vez en diferentes máquinas (o en la misma máquina si solo proporciona 'localhost'. El ejecutable en sí (mpifork) termina, después de llamar
execvp
, ya no se ejecuta en la primera máquina.Si quisieras ser malvado, puedes hacer este lanzamiento en cada máquina, incluyendo la lista completa de hosts que se proporciona en la línea de comando
args
. Eso volvería a generar una copia de sí mismo en cada máquina, una y otra vez: una bifurcación en racimo.Sin embargo, de esta forma, estoy bastante seguro de que esto cumple con las reglas.
fuente
JavaScript
Sin "ir a la red" cuando no es necesario :-) La programación del bucle de eventos de JavaScript nos permite escribir programas que cumplen los requisitos dados muy fácilmente:
Esto "reinicia" la
program
función a un ritmo de 10 veces por segundo. La naturaleza de JavaScript garantiza que solo se ejecutará una sola tarea al mismo tiempo, y no "reiniciará el entorno" como en "volver a cargar la página".fuente
Asamblea x86
No estoy completamente seguro de que esto se ajuste a sus criterios, ya que no genera un nuevo proceso, pero aquí está de todos modos.
El programa mostrará un cuadro de mensaje, asignará algo de memoria, copiará su propia sección de código en la memoria asignada y luego saltará a esa ubicación comenzando el ciclo. Debería ejecutarse hasta que malloc falle.
Compilado con fasm.
fuente
@
vez que lo hagas, ya que probablemente no lo vigile).Linux upstart init
Dada la lectura más estricta de la pregunta, creo que esto es imposible. En esencia, está pidiendo un programa que comience espontáneamente con la ayuda de ningún otro programa en ejecución.
Hay algunos
at
ychron
basados en las respuestas, pero con la lectura más estricta,atd
yanacron
son los programas complementarios que están funcionando todo el tiempo, por lo que pueden ser descalificados.Un enfoque relacionado, pero un poco más bajo es usar Linux
init
. Como root, agregue este archivo .conf a/etc/init/
:Luego
init
vuelva a leer sus archivos .conf:Esto iniciará un
sleep
proceso que durará 10 segundos y luego saldrá.init
luego reaparecerásleep
una vez que detecte que el anterior se ha ido.Por supuesto, esto todavía se está utilizando
init
como un programa complementario. Se podría argumentar queinit
es una extensión lógica del núcleo y siempre estará disponible en cualquier Linux.Si esto no es aceptable, entonces supongo que el siguiente paso sería crear un módulo de kernel que reaparezca un proceso de espacio de usuario (no estoy seguro de lo fácil que es). Aquí se puede argumentar que el núcleo no es un proceso y, por lo tanto, no es un programa (complementario). Por otro lado, el núcleo es un programa en sí mismo, desde el punto de vista de la CPU.
fuente
TI-BASIC: 5 caracteres
llámalo
prgmA
fuente
:
es solo el símbolo de inicio de línea siempre que esté programando en TI-basic. No es algo que escribes, solo está allí en el editor.A
y usar un valor de él como un caso base, verá que eventualmente saldrá.