11
votes

Comment puis-je exécuter une commande système en perl de manière asynchrone?

J'ai actuellement un script Perl qui exécute une commande externe sur le système, rassemble la sortie et effectue une action basée sur ce qui a été renvoyé. En ce moment, voici comment j'exécute cela (où $ cmd est une chaîne avec la configuration de la commande): xxx

J'aimerais modifier cela, donc si la commande se bloque et ne renvoie pas Valeur après tant de fois, je tue la commande. Comment allais-je continuer à courir cette asynchrone?


0 commentaires

3 Réponses :


12
votes

Il y a beaucoup de façons de faire ceci:

  • Vous pouvez le faire avec une fourchette (fourche-four perdoc -f)
  • ou en utilisant des threads (fils Perldoc). Ces deux apportent la transmission des informations retournées au programme principal difficile.
  • sur les systèmes qui le supportent, vous pouvez définir une alarme d'alarme (Alarme Perldoc -f), puis nettoyez-la dans le gestionnaire de signal.
  • Vous pouvez utiliser une boucle d'événement comme Poe ou CORO.
  • au lieu des backtsks, vous pouvez utiliser Open () ou respectivement Open2 ou Open3 (cf. IPC :: Open2, IPC :: Open3) Pour démarrer un programme tout en obtenant son stdout / stardr via une poignée de fichier. Exécuter des opérations de lecture non bloquantes sur elle. (Perldoc -F Sélectionnez et probablement Google "Perl NONBLOCKINGING READ")
  • comme une variante plus puissante de l'OpenX () 's, consultez IPC :: Run / IPC :: cmd.
  • probablement des tonnes que je ne peux pas penser au milieu de la nuit.

2 commentaires

Sur Win32 Systems Systems Faites vue sur Broken Sélectionner qui ne fonctionne que pour les sockets et les interactions potentiellement étranges avec les fenêtres de la console, WPERL (exécute Perl de manière non console, mais a des effets étranges sur les processus STDIO et ENFANT) . Sur le côté de plus, vous pouvez faire un système (-1, 'foo') . En outre, certains moyens de démarrer un processus échouent après avoir exécuté 64 enfants. Ime, win32 :: processus :: créer () est le moyen le plus sûr d'exécuter un programme dans le BGRND.


@DaoToad, merci pour ce commentaire. Mon manque d'indice Win32 montre que la seule chose que je connaisse est que la fourchette () est imitée avec des threads et que vous ne pouvez pas utiliser l'alarme. Je suppose que si Win32 est impliqué, IPC :: cmd serait un bon choix.



1
votes

Si votre programme externe ne prend aucune entrée, recherchez les mots suivants dans le Perlipc Manpage:

Voici un backtick ou une tuyau de sécurité en lecture seule:

Utilisez l'exemple de code et gardez-le avec une alarme (qui est également expliquée dans perlipc ).


0 commentaires

8
votes

Si vous avez vraiment besoin de mettre un délai d'attente sur un appel système donné, c'est un problème beaucoup plus simple que la programmation asynchrone.

Tout ce dont vous avez besoin est une alarme () à l'intérieur d'un bloc EVAL ().

Voici un exemple de bloc de code qui les met dans un sous-programme que vous pourriez tomber dans votre code. L'exemple appelle le sommeil, alors n'est pas excitant pour la sortie, mais vous montre la fonctionnalité de délai d'attente qui vous intéressait. Sortie de fonctionnement est:

/ bin / dort 2 échec: délai d'attente à ./Time-out ligne 15. xxx


2 commentaires

Merci, c'est plus ce que je cherchais.


Je pense que vous aurez besoin d'un \ n dans le message de matrice. ( perdoc.perl.org/functions/alarm.html )