Pergunta

Eu tenho um processo de longa duração e eu preciso dele para lançar outro processo (que será executado por um bom tempo também). Eu preciso começar a ele só, e depois esquecer-se completamente sobre isso.

Eu consegui fazer o que eu precisava escavando algum código a partir do livro de Ruby programação, mas eu gostaria de encontrar a melhor maneira / direita, e entender o que está acontecendo. Aqui está o que eu tenho inicialmente:

exec("whatever --take-very-long") if fork.nil?
Process.detach($$)


Então, este é o caminho, ou que outra forma eu deveria fazê-lo?

Depois de verificar as respostas abaixo eu acabei com este código, o que parece fazer mais sentido:

(pid = fork) ? Process.detach(pid) : exec("foo")


Eu apreciaria uma explicação sobre como fork funciona. [Tenho que já]

Foi destacando $$ certo? Eu não sei por que isso funciona, e eu realmente adoraria ter uma melhor compreensão da situação.

Foi útil?

Solução

A função fork separa o seu processo em dois.

Ambos processos, em seguida, receber o resultado da função. A criança recebe um valor de zero / nil (e, portanto, sabe que é a criança) e o pai recebe o PID da criança.

Assim:

exec("something") if fork.nil?

fará com que o processo filho começar "algo", e o processo pai vai continuar com onde estava.

Note que exec() substitui o processo atual com "algo", de modo que o processo filho nunca vai executar qualquer código Ruby posterior.

A chamada para olhares Process.detach() como ele pode estar incorreta. Eu teria esperado que ele tenha PID da criança nele, mas se eu ler o seu código de direito é realmente desanexar o processo pai.

Outras dicas

Alnitak é certo. Aqui está uma forma mais explícita para escrevê-lo, sem $$

pid = Process.fork
if pid.nil? then
  # In child
  exec "whatever --take-very-long"
else
  # In parent
  Process.detach(pid)
end

O objetivo da desconexão é apenas para dizer: "Eu não me importo quando a criança termina" para evitar zombie processa .

Detaching $$ não estava certo. De p. 348 da picareta (2ª Ed):

$$ Fixnum O número do processo do programa que está sendo executado. [R / o]

Esta seção, "Variáveis ??e Constantes" no capítulo "Ruby Language", é muito útil para a descodificação de várias constantes $ curtas rubi - no entanto, a edição on-line (o primeiro

Então, o que você estava realmente fazendo era destacar o programa de si mesmo, não de seu filho. Como já foi dito, a maneira correta de separar a criança é usar pid da criança voltou de fork().

As outras respostas são bons, se você tem certeza que deseja desanexar o processo filho. No entanto, se você não quer se importa, ou prefere manter o processo filho anexado (por exemplo, você está lançando sub-servidores / serviços para um aplicativo web), então você pode tirar proveito da seguinte atalho

fork do
    exec('whatever --option-flag')
end

Proporcionar um bloco diz garfo para executar esse bloco (e somente esse bloco) no processo filho, enquanto continua em no pai.

i encontrou as respostas acima quebrou meu terminal e errei a saída. esta é a solução que eu encontrei.

   system("nohup ./test.sh &")

apenas no caso de alguém tem o mesmo problema, meu objetivo era entrar em um servidor ssh e depois manter esse processo funcionando indefinidamente. assim test.sh é este

#!/usr/bin/expect -f
spawn ssh host -l admin -i cloudkey  
expect "pass"
send "superpass\r"
sleep 1000000
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top