2014-05-11 1 views
3

J'ai un morceau de code dans Julia dans lequel un solveur itére de nombreuses fois car il cherche une solution à un problème très complexe. À l'heure actuelle, je dois fournir un certain nombre d'itérations pour le code à faire, régler assez bas que je ne dois pas attendre des heures pour que le code s'arrête afin de sauver l'état actuel, mais assez élevé que je ne sais pas continuer à activer le code toutes les 5 minutes.Détecter des frappes dans Julia

Existe-t-il un moyen, avec l'état actuel de Julia (0.2), de détecter une frappe au clavier pour qu'elle se termine sans enregistrer (en cas de problème) ou se terminer par une sauvegarde? J'ai besoin d'une méthode telle que le code continue sans entrave, sauf si un tel événement de frappe est arrivé, et cela va interrompre à n'importe quelle itération. Essentiellement, je cherche une commande qui lira dans une frappe si une frappe est survenue (tandis que le terminal que Julia court dedans a le focus), et exécute certain code si la frappe était une clef spécifique. Est-ce possible?

Remarque: Je cours julia via xfce4-terminal sur Xubuntu, dans le cas où cela affecte la commande requise.

+0

Ce que vous voulez faire est dans le domaine de la programmation du terminal. Cela implique généralement de modifier le terminal actuel, puis d'écouter les frappes. Je ne suis pas au courant des paquets en julia qui vous permettent de faire cela actuellement. –

+0

J'ai trouvé un moyen d'obtenir les résultats voulus grâce à une implémentation d'interface graphique Tk avec "Enregistrer" qui déclenche l'arrêt du code lors de l'itération suivante et "Annuler" qui déclenche une erreur pour arrêter le code sans enregistrer. Je laisse la question ouverte parce que ma solution ne fournit pas une méthode de détection de frappe, et il doit y avoir une méthode de détection de frappe pour Julia. –

Répondre

1

Vous pouvez y parvenir en envoyant une interruption (Ctrl+C). Cela devrait fonctionner à partir du REPL sans aucune modification de votre code - si vous voulez implémenter la sauvegarde, vous devrez gérer le InterruptException résultant et inviter l'utilisateur.

+0

Existe-t-il un moyen de faire en sorte que le code continue à partir du moment où l'exception a été levée? Sans quelque chose comme ça, je ne vois pas comment gérer la situation dans laquelle l'exception est levée pendant que les variables importantes sont en train d'être mises à jour. –

+0

Je pense que la seule façon de le faire serait de répéter le gestionnaire d'exception à ces points (peut-être en utilisant une macro pour éviter trop de répétition). –

2

Vous pouvez vous charger d'une tâche asynchrone à partir de STDIN, en bloquant jusqu'à ce que quelque chose soit disponible pour la lecture. Dans votre tâche de calcul principale, lorsque vous êtes prêt à vérifier l'entrée, vous pouvez appeler yield() pour donner quelques cycles à la tâche de lecture, et vérifier un global pour voir si quelque chose a été lu. Par exemple:

input = "" 
@async while true 
    global input = readavailable(STDIN) 
end 
for i = 1:10^6 # some long-running computation         
    if isempty(input) 
     yield() 
    else 
     println("GOT INPUT: ", input) 
     global input = "" 
    end 
    # do some other work here             
end 

Notez que, puisque c'est multithread coopératif, il n'y a pas des conditions de course.

+0

Merci pour votre idée, mais je n'arrive pas à faire marcher ça. Si je l'ai en boucle 1:10 et le faire effectuer réduire (*, 1: gros (500000)) pour lui donner quelque chose de lent à faire dans la partie "faire un autre travail ici", alors tapez quelque chose en cours d'exécution, ne s'arrête pas du tout (pour l'entrée, je veux dire - il fonctionne juste jusqu'à ce qu'il ait fini le traitement). Ceci est vrai à la fois s'il est exécuté régulièrement et s'il est exécuté avec un processus supplémentaire (julia -p 1). J'utilise 0.2.1 - cela pourrait-il être le problème? –

Questions connexes