Escreva um programa que se inicie novamente quando terminar.
Não deve haver mais de uma instância do programa em execução ao mesmo tempo. Nem mesmo por um leve momento.
Você pode ignorar qualquer instância que seja iniciada manualmente pelo usuário durante seu ciclo. Mas seu código não deve fazer isso no seu ciclo de reinicialização.
O programa pode iniciar após qualquer período de tempo, desde que seja garantido que ele será iniciado novamente.
A única maneira de parar o ciclo é matar o processo.
Sua solução não deve envolver a reinicialização do ambiente (no qual o programa está sendo executado, inclui SO, máquina, VM, shell, etc.). Somente seu programa tem permissão para reiniciar.
popularity-contest
microbiano
fonte
fonte
exec
acontece no linux?shutdown -r -t 0 -f
".Respostas:
Roteiro Bash, 3 caracteres (o mais curto, possivelmente o mais elegante, embora seja reconhecidamente controverso)
Simplesmente coloca uma nova instância de si mesma em segundo plano (novo processo) e sai. A nova instância provavelmente permanecerá na fila de execução do planejador até que a instância anterior seja concluída.
Aviso - isso é difícil
kill
, pois o PID está mudando continuamente. Renomear temporariamente o arquivo de script é provavelmente a maneira mais simples de interromper o ciclo.Um sistema de núcleo único é assumido. É claro que isso não é realista com o Linux no hardware bare-metal moderno, mas é facilmente configurável quando executado em uma VM. Provavelmente, poderíamos conseguir um truque semelhante usando
taskset
, mas isso reduziria o impacto da solução de 3 caracteres.Esta resposta dobra as regras um pouco, pois aplica um significado específico de "execução". Haverá momentos em que o novo processo foi
fork()
editado e o antigo processo ainda está ativo - ou seja, pode ser possível observar mais de um PID. No entanto, o novo processo será colocado na fila de execução do planejador Linux para aguardar os ciclos da CPU, enquanto o processo existente continuará sendo executado. Neste ponto, tudo o que precisa ser feito pelo processo existente é porbash
si sóexit()
. Isso leva uma quantidade finita de tempo, embora eu esteja bastante confiante de que isso será feito muito antes do atual quantum de divisão do tempo / agendador. A evidência de suporte é o fato debash
iniciar e desligar em 2ms na minha VM:Evidências adicionais de apoio de que o novo processo não é realmente executado até que o processo anterior esteja concluído podem ser vistas na
strace
saída:Na saída, vemos que o processo original possui o PID 6929. Podemos ver a
fork()
chamada (na verdadeclone()
), que retorna um novo PID de 6930. Nesse momento, existem 2 PIDs, mas apenas 6929 estão em execução no momento:strace
Saída total aqui.Podemos ver que o 6930 não emite nenhuma chamada do sistema até que o 6929 esteja completo. É razoável supor que isso significa que o 6930 não é executado até que o 6929 esteja concluído. O
perf
utilitário seria a melhor maneira de provar isso.fonte
top
não é a ferramenta certa para usar aqui. No entanto, vejo quetime bash -c :
leva apenas 2ms na minha VM do Ubuntu, então não acho razoável esperarbash
concluir seu desligamento antes que seu quantum de agendamento seja feito.Solução 1
PHP, 32 caracteres
Ele envia o cabeçalho e depois para. Após 3 segundos, a página é recarregada.
arquivo a.php
Isso pode ser interrompido encerrando a execução da página antes do envio dos cabeçalhos ou simplesmente matando o navegador.
Solução 2
PHP, 2 páginas
Vamos considerar os dois arquivos dois programas diferentes. Os dois arquivos estão na mesma pasta.
arquivo a.php
arquivo b.php
O encerramento de uma das páginas antes do envio dos cabeçalhos encerra o programa (interromper o navegador também funciona).
Aqui está o mesmo programa em
ASP.NET
arquivo a.aspx
arquivo b.aspx
fonte
sh
Isso funcionará em qualquer sistema compatível com Posix.
Para matá-lo, exclua o arquivo ou use
atrm
.fonte
bater
exec
substitui o shell sem criar um novo processo. Isso garante que não possa haver uma segunda instância.fonte
~/.bash_profile
!$0
é-bash
quando.bash_profile
é originada, o que resultaria apenas em um erro de sintaxe.exec ${0##-}
em~/.bash_profile
obras :-)Agendador de tarefas do Windows (nativo)
C ++. Um pesadelo da programação COM. Atende a todos os requisitos de desafio.
Compile com MSVC (ou MinGW GCC se você tiver todas as dependências).
O programa iniciará e registrará uma tarefa única com o agendador de tarefas do Windows para iniciar-se 5 segundos depois (Painel de Controle -> Ferramentas Administrativas -> Agendador de Tarefas para visualizar, a tarefa é denominada "Restarter"). O programa fará uma pausa por 5 segundos para lhe dar uma chance de matá-lo antes de criar a tarefa.
Requisitos do Desafio:
Inicia-se novamente quando termina. Sim. A tarefa é agendada imediatamente antes da saída do programa.
Não há mais de uma instância do programa em execução ao mesmo tempo. Sim. O programa sai totalmente e não é executado por 5 segundos. É iniciado pelo planejador.
Você pode ignorar qualquer instância que seja iniciada manualmente pelo usuário durante seu ciclo. Sim, como efeito colateral do uso de um nome de tarefa constante.
Contanto que seja garantido que ele recomeça. Sim, desde que o Agendador de tarefas esteja em execução (ele está em uma configuração padrão do Windows).
A única maneira de parar o ciclo é matar o processo. Sim, o processo pode ser interrompido durante a janela de 5 segundos enquanto estiver em execução. O programa exclui a tarefa antes do atraso de 5 segundos, eliminá-la neste momento não deixará uma tarefa perdida no agendador.
Sua solução não deve envolver a reinicialização do ambiente Sim.
A propósito, se alguém já se perguntou por que os aplicativos Windows eram tão instáveis (antes do advento do .NET e C #), esse é um dos motivos. A quantidade de manipulação de erros necessária (se eu a incluísse), o gerenciamento de recursos e a verbosidade configuram situações muito propensas a erros se um programador é mesmo um pouquinho preguiçoso (o código acima é extremamente preguiçoso).
Uma alternativa muito mais fácil e mais curta é invocar o schtasks.exe. Enviei uma versão com isso também em um script .BAT .
fonte
BBC BASIC - uma homenagem ao Snow Patrol
Emulador em bbcbasic.co.uk
Este é um pouco diferente. Ele imprime um verso da música "Run" e toca um arpejo dos acordes para que você possa cantar junto. Foi inspirado pelo fato de que o comando para executar (e, portanto, a última linha do programa) é, obviamente, EXECUTAR.
Todas as variáveis são limpas no início do programa; portanto, a cor da tela deixada pela iteração anterior decide o versículo a ser impresso a seguir.
SAÍDA (montagem de 4 capturas de tela diferentes)
fonte
HTML / JavaScript:
O código aciona a destruição da página em que está sendo executada e a recriação de outra instância quando o navegador carrega a página novamente.
AFAIK, a única saída é matar a guia na qual a página está sendo executada.
EDIT: conforme solicitação popular, um código HTML5 válido:
fonte
C
Este programa atua como muitos malwares. Antes de fechar, ele cria um script de shell no diretório / tmp. É necessário iniciar o shell script, o que permite que o programa original feche e cancele o PID original. Após um breve período de tempo (2 segundos), o shell script inicia um novo processo com o programa. Por uma questão de brevidade, o local do programa é conectado como '/ tmp / neverend /'.
Existe apenas um processo sem fim em execução por vez. Cada novo processo recebe um novo PID. A maneira mais fácil de eliminar isso é excluir o executável. Se você quiser torná-lo mais maligno, copie o executável e o script para garantir que haja várias cópias no programa em disco a qualquer momento.
fonte
system()
se as regras não contarem um fork + exec/bin/sh
como um programa suplementar.Perl
O script emite um comando do sistema para se matar e direcionar o resultado para outra instância. O intérprete Perl é usado para matar, por razões de plataforma cruzada.
Pare a loucura excluindo o script.
fonte
Atari básico de 8 bits
Tokeniza para:
Internamente, ele limpa as estruturas internas, basicamente eliminando o programa, antes de executá-lo novamente a partir da listagem.
Isso é fundamentalmente diferente de:
Que tokeniza para:
Este é um loop infinito básico. Ao executá-las, você vê a diferença de velocidade (a primeira é mais lenta).
fonte
LIST
, você não o veria correndo. Eu escolhiLIST
porque tem a menor entradaL.
. Eu gosto da idéia de colocar isso em um buffer de teclado, é certamente curto o suficiente!Return
? Qual é o tamanho do buffer do teclado? No VIC-20 e C64, são dez bytes. Um programa que faz toques suficientes para carregar o buffer do teclado provavelmente não se encaixaria no buffer do teclado, mas escrevi programas que se modificariam imprimindo alterações na tela seguidasRUN
eReturn
pressionando algumas teclas. Tais coisas foram especialmente úteis nos 64, pois não possuíam oIN
comando [IIRC] que o Atari possui para mesclar linhas em um programa.Em um IBM Mainframe executando o z / OS, você executa um utilitário que copia um conjunto de dados (arquivo) para outro conjunto de dados (arquivo). A entrada é a fonte da JCL (Job Control Language) que você enviou para fazer com que ela seja executada. A saída é o leitor interno (INTRDR). Você também precisará garantir que seu sistema não permita a execução de vários nomes de tarefas idênticos. É bom usar uma classe de trabalho que possui apenas um iniciador (local onde um JOB pode ser executado em lote).
Não há PIDs envolvidos (no z / OS), portanto falha no conjunto de desafios.
Você interrompe o processo drenando e / ou lavando. Se algo der errado, drenando e / ou lavando, xingando, chutando, tentando um arranque a quente e, finalmente, iniciando a frio ou pressionando o Grande Botão Vermelho (e disparando no programador).
Eu posso ter exagerado ao longo do caminho, mas não tente fazer isso no trabalho ...
Exemplo usando SORT. Os detalhes no cartão JOB são muito dependentes do site. A política do site pode proibir ou impedir o uso do INTRDR. Uma classe específica pode ser necessária para usar o INTRDR. Se a política do site proibir seu uso , não a use, a menos que você queira levar seus pertences para passear em uma caixa de papelão.
Embora haja bons usos para o INTRDR, não o utilize para esse fim . Você nem terá a chance de pegar sua caixa.
Outros utilitários estão disponíveis. Um programa rápido também seria fácil, basta ler um arquivo, escrever um arquivo.
Se você quiser que um exemplo disso dê errado, tente: http://ibmmainframes.com/viewtopic.php?p=282414#282414
A maneira tradicional de copiar um conjunto de dados é usar o utilitário IBM IEBGENER, como a ugoren faz alusão em seus comentários.
No entanto, atualmente, muitos sites têm o IEBGENER "alias" para o ICEGENER. O ICEGENER, se puder, usará o DFSORT da IBM (ou seu rival SyncSort) para fazer uma cópia, porque os produtos SORT são muito mais otimizados para IO do que o IEBGENER.
Estou apenas cortando o intermediário usando SORT.
Se você trabalha em um site IBM Mainframe, conhece o formato da placa JOB que deve usar. O cartão mínimo de trabalho é como eu mostrei, sem o comentário. O comentário será importante, porque você pode estar fornecendo informações contábeis, por exemplo. O nome do trabalho provavelmente terá um formato específico do site.
Alguns sites proíbem ou impedem o uso do INTRDR. Estar ciente.
Alguns sites permitem que vários trabalhos com o mesmo nome sejam executados ao mesmo tempo. Estar ciente.
Embora, a menos que você seja um programador do sistema, não possa configurar essa classe, procure uma classe que permita apenas um iniciador. Com isso, o processo é bastante seguro - mas tenha certeza absoluta de que a classe está funcionando como descrito. Teste. Não com este trabalho.
Se você é um programador do sistema, sabe que não deve fazer nada fora do seu mandato. disse nuff.
Com um trabalho com o mesmo nome permitido ao mesmo tempo e um único iniciador, este será um fluxo constante de início / término do trabalho próximo / início / término do trabalho - até você preencher o spool (outra coisa ruim a fazer) com a saída de milhares de trabalhos (ou os números acabam). Assista a um console JES para obter mensagens de aviso.
Basicamente, não faça isso. Se você fizer isso, não faça em uma máquina de produção.
Com um pouco de detalhamento, considerarei outra resposta sobre como fazê-lo em outro sistema operacional IBM Mainframe, z / VSE ... z / VSE usa JCL. O z / OS usa JCL. Eles são diferentes :-)
fonte
IEBGENER
época, costumávamos simplesmente copiar.Python (72 bytes)
Poderia ser menor, eu acho. Primeiro, codificando o nome do arquivo (em vez de usá-lo
__file__
). Mas aqui, você pode colocar esse código em um arquivo e executá-lo, seja qual for o nome :)fonte
&&
para&
.Agendador de tarefas do Windows (.BAT)
Script em lote do Windows. Atende a todos os requisitos de desafio.
Até onde posso ver, esta é a única solução do Windows até agora que atende a todos os requisitos e não possui dependências fora do padrão (minha outra solução é semelhante, mas requer compilação).
O programa se comporta de maneira semelhante à minha resposta C ++ / COM .
O programa iniciará e registrará uma tarefa única no agendador de tarefas do Windows para iniciar-se até 60 segundos depois (Painel de Controle -> Ferramentas Administrativas -> Agendador de Tarefas para visualizar, a tarefa é denominada "Restarter"). O programa fará uma pausa por 5 segundos para lhe dar uma chance de matá-lo antes de criar a tarefa.
Faz uso da interface do Agendador de tarefas da linha de comando
schtasks.exe
. A aritmética no script é calcular as compensações de tempo, mantendo o tempo válido e no formato HH: MM.Requisitos do Desafio:
Inicia-se novamente quando termina. Sim. A tarefa é agendada imediatamente antes da saída do programa.
Não há mais de uma instância do programa em execução ao mesmo tempo. Sim. O programa sai completamente e não é executado por ~ 60 segundos. É iniciado pelo planejador.
Você pode ignorar qualquer instância que seja iniciada manualmente pelo usuário durante seu ciclo. Sim, como efeito colateral do uso de um nome de tarefa constante.
Contanto que seja garantido que ele recomeça. Sim, desde que o Agendador de tarefas esteja em execução e o schtasks.exe esteja presente (ambos verdadeiros nas configurações padrão do Windows).
A única maneira de parar o ciclo é matar o processo. Sim, o processo pode ser interrompido durante a janela de 5 segundos enquanto estiver em execução. O programa exclui a tarefa antes do atraso de 5 segundos, eliminá-la neste momento não deixará uma tarefa perdida no agendador.
Sua solução não deve envolver a reinicialização do ambiente Sim.
Nota: Devido à interface limitada da linha de comandos, o tempo de reinicialização deve ser especificado em minutos e a tarefa não será reiniciada nos laptops sem o adaptador CA conectado (desculpe).
fonte
Shell Unix
Ainda não vi muitas soluções que dependem de um programa não relacionado para reiniciá-lo. Mas é exatamente para isso que o
at(1)
utilitário foi criado:É difícil realmente pegar o programa em execução, pois ele é executado apenas uma vez por minuto e sai tão rapidamente. Felizmente, o
atq(1)
utilitário mostra que ainda está funcionando:E
atrm(1)
permitirá que você quebre o ciclo:Você pode substituir
1 minute
por1 hour
, ou1 week
. Ou dê1461 days
um programa que seja executado uma vez a cada 4 anos.fonte
PowerShell
Estou abusando (e possivelmente violando) minha própria regra.
Leva uma quantidade infinita de tempo para se reiniciar.
Pode ser eliminado matando o processo host.
Apenas espere e veja;)
fonte
while true; do sleep 1; done
quilifica, não é?Bater
Salve isso como repeat.sh no diretório / e conceda permissão de execução. Pode ser eliminado excluindo o arquivo
Isso funciona colocando uma entrada no crontab para executá-lo 1 minuto depois.
fonte
Visual Base 6 :)
Para executar, crie um novo projeto, adicione um módulo com esse código, defina o objeto de inicialização como "Sub Main", compile e execute o executável.
Versão mais legível:
fonte
HTML / JAVASCRIPT
ARQUIVO HTML a.html
fonte
Bater
Mais tempo do que deve ser, mas estou cansado e não me importo :)
Você disse que ele precisa se reiniciar quando terminar, não disse especificamente que tinha que fazê-lo repetidamente ou indefinidamente. Além disso, você disse que nunca deve haver duas instâncias em execução ao mesmo tempo ... isso nunca acontecerá. ;)
Existem várias maneiras de fazer isso. Meu favorito pessoal, seria fazer algo como enviar um pacote para algum lugar distante e, em seguida (através de vários métodos), fazer com que a resposta iniciasse o processo.
fonte
sleep
processo reinicia quando terminaAndroid: um alarme reiniciará a atividade após 1 segundo
fonte
Ambiente C + MPI
mpifork.c:
Você deve ter o OpenMPI ou alguma outra implementação MPI instalada.
Ajuntar comAgora que penso nisso, não há razão para você usar o mpicc - gcc ou qualquer outro compilador que funcione. Você só precisa ter mpirun.Para executá-lo, você provavelmente deve incluir o nome completo do caminho e uma lista de hosts. Por exemplo, adicionei algumas entradas no / etc / hosts que apontavam para o localhost e executei-o assim:
O executável deve estar no mesmo diretório em qualquer máquina em que você deseja executá-lo.
Essencialmente, isso pega uma lista de hosts fornecidos na linha de comando, seleciona um dos hosts e inicia o executável no host de destino com os mesmos argumentos. Se tudo correr perfeitamente, o mpirun se chamará repetidamente em máquinas diferentes (ou a mesma máquina se você fornecer apenas 'localhost'. O próprio executável (mpifork) termina - após chamar
execvp
, ele não está mais sendo executado na primeira máquina.Se você quisesse ser mau, poderia fazer esse lançamento em todas as máquinas, incluindo a lista completa de hosts fornecidos na linha de comando em
args
. Isso geraria uma cópia de si mesma em todas as máquinas, repetidas vezes - um forkbomb de cluster.No entanto, nesta forma, tenho certeza de que isso satisfaz as regras.
fonte
Javascript
Sem "ir para a rede" quando não é necessário :-) O agendamento do loop de eventos do JavaScript nos permite escrever programas que atendem aos requisitos fornecidos com muita facilidade:
Isso "reinicia" a
program
função em um ritmo de 10 vezes por segundo. É garantido pela natureza do JavaScript que apenas uma única tarefa será executada ao mesmo tempo e não "reinicia o ambiente", como em "recarregar a página".fonte
Montagem x86
Não tenho certeza absoluta de que isso se encaixa nos seus critérios, pois não gera um novo processo, mas aqui está mesmo assim.
O programa mostrará uma caixa de mensagem, alocará um pouco de memória, copiará sua própria seção de código na memória alocada e, em seguida, pulará para esse local iniciando o ciclo. Deve ser executado até o malloc falhar.
Compilado com fasm.
fonte
@
assim que conseguir, pois provavelmente não vou ficar de olho nela).Linux iniciante iniciante
Dada a leitura mais estrita da questão, acho que isso é impossível. Em essência, ele está solicitando que um programa inicie espontaneamente com a ajuda de outros programas em execução.
Existem alguns
at
echron
baseados em respostas, mas com a leitura mais rigorosa,atd
eanacron
são programas complementares que estão funcionando o tempo todo, para que eles possam ser desqualificado.Uma abordagem relacionada, mas um nível um pouco mais baixo é usar o Linux
init
. Como root, adicione este arquivo .conf ao/etc/init/
:Então tem
init
leia novamente seus arquivos .conf:Isso iniciará um
sleep
processo que permanecerá por 10 segundos e depois sairá.init
reaparecerásleep
assim que detectar que o anterior desapareceu.Claro que isso ainda está sendo usado
init
como um programa suplementar. Você pode argumentar queinit
é uma extensão lógica do kernel e irá sempre estará disponível em qualquer Linux.Se isso não for aceitável, acho que a próxima coisa a ser feita em nível inferior seria criar um módulo do kernel que reaparece no processo do espaço do usuário (não sei o quão fácil isso é). Aqui pode-se argumentar que o kernel não é um processo e, portanto, não é um programa (suplementar). Por outro lado, o kernel é um programa por si só, do ponto da CPU.
fonte
TI-BASIC: 5 caracteres
chame-o
prgmA
fonte
:
símbolo é apenas o início da linha sempre que você estiver programando no TI-basic. Não é algo que você digita, está apenas no editor.A
e usar um valor dele como um caso base.