Question

J'ai un long processus et j'en ai besoin pour lancer un autre processus (qui durera aussi longtemps). Je n'ai besoin que de le démarrer et de l'oublier complètement.

J'ai réussi à faire ce dont j'avais besoin en récupérant du code dans le livre Programming Ruby, mais j'aimerais trouver la meilleure façon, et comprendre ce qui se passe. Voici ce que j'ai au début:

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


Alors, est-ce la bonne façon de faire ou comment devrais-je le faire?

Après avoir vérifié les réponses ci-dessous, je me suis retrouvé avec ce code, qui semble plus logique:

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


J'aimerais avoir des explications sur le fonctionnement de fork . [Je l'ai déjà]

Le détachement de $$ était-il correct? Je ne sais pas pourquoi cela fonctionne et j'aimerais vraiment mieux comprendre la situation.

Était-ce utile?

La solution

La fonction fork sépare votre processus en deux.

Les deux processus reçoivent ensuite le résultat de la fonction. L’enfant reçoit la valeur zéro / nil (et sait donc qu’il s’agit de l’enfant) et le parent reçoit le PID de l’enfant.

D'où:

exec("something") if fork.nil?

fera en sorte que le processus enfant commence par "quelque chose", et le processus parent continuera à son niveau actuel.

Notez que exec () remplace le processus actuel par "quelque chose" afin que le processus enfant n'exécute jamais aucun code Ruby ultérieur.

L'appel à Process.detach () semble indiquer qu'il est peut-être incorrect. Je me serais attendu à ce qu'il contienne le PID de l'enfant, mais si je lis correctement votre code, il détache le processus parent.

Autres conseils

Alnitak a raison. Voici un moyen plus explicite de l'écrire, sans $$

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

L’objectif de détachement est juste de dire: "Je ne me soucie pas de la fin de l’enfant" éviter les processus zombie .

Détacher $$ n’était pas correct. À partir de p. 348 de la pioche (2e éd):

  

$$ Fixnum Numéro de processus du programme en cours d'exécution. [r / o]

Cette section, "Variables et constantes" dans la " Ruby Language " chapitre, est très pratique pour décoder diverses constantes $ ruby ??- quelle que soit l'édition en ligne (la première

Donc, ce que vous faisiez réellement était de détacher le programme de lui-même, pas de son enfant. Comme d'autres l'ont déjà dit, le moyen approprié de se détacher de l'enfant consiste à utiliser le pid de l'enfant renvoyé par fork () .

Les autres réponses sont utiles si vous êtes certain de vouloir détacher le processus enfant. Toutefois, si cela ne vous dérange pas ou si vous préférez garder le processus enfant attaché (par exemple, vous lancez des sous-serveurs / services pour une application Web), vous pouvez tirer parti du raccourci suivant

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

Fournir un bloc indique à fork d'exécuter ce bloc (et seulement ce bloc) dans le processus enfant, tout en continuant dans le parent.

J'ai trouvé les réponses ci-dessus cassées mon terminal et foiré la sortie. c'est la solution que j'ai trouvée.

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

juste au cas où quelqu'un aurait le même problème, mon objectif était de vous connecter à un serveur ssh, puis de faire en sorte que ce processus s'exécute indéfiniment. alors test.sh est-ce

#!/usr/bin/expect -f
spawn ssh host -l admin -i cloudkey  
expect "pass"
send "superpass\r"
sleep 1000000
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top