Question

J'ai une application GUI python qui utilise une longue fonction en cours d'exécution d'un .donc / .dll appelle par ctypes.

Je cherche un moyen de communiquer avec la fonction alors qu'il est en cours d'exécution dans un thread séparé ou d'un processus, afin que je puisse le demander de mettre fin tôt (ce qui nécessite un travail sur le côté C avant de retourner un résultat partiel). Je suppose que cela aura besoin d'une sorte de signal de réception ou de lecture des tuyaux, mais je veux le garder aussi simple que possible.

Qu'est-ce que vous, la meilleure approche pour résoudre ce genre de problème? Je suis en mesure de changer le code sur les deux côtés python et C.

Était-ce utile?

La solution

Il y a deux parties dont vous aurez besoin de répondre ici: un si la façon de communiquer entre les deux processus (votre interface graphique et le processus d'exécuter la fonction), et l'autre est de savoir comment changer votre fonction il répond aux requêtes asynchrones ( « oh, on m'a dit de revenir tout ce que j'ai »).

Travailler la réponse à la deuxième question déterminera probablement la réponse à la première. Vous pouvez le faire par des signaux (dans ce cas, vous obtenez un gestionnaire de signal qui obtient le contrôle du processus, peut rechercher des instructions plus détaillées ailleurs, et modifier vos structures de données internes avant de rendre le contrôle à votre fonction), ou vous pourriez avoir votre fonction surveiller une interface de commande pour les commandes (chaque milliseconde, vérifier s'il y a une attente de commande, et s'il y a, voir ce qu'il est).

Dans le premier cas, vous voulez un traitement du signal ANSI C (signal (), sighandler_t), dans le second, vous voudrez probablement un tuyau ou similaire (tuyau () et sélectionnez ()).

Autres conseils

Vous mentionnez que vous pouvez changer à la fois les côtés C et Python. Pour éviter d'avoir à écrire des prises de courant ou code de signal en C, il pourrait être plus facile de briser la grande fonction C en 3 fonctions séparées plus petites que la configuration, une petite parcelle de travail, et le nettoyage. La parcelle de travail devrait se situer entre environ 1 ms et 1 seconde de l'exécution pour trouver un équilibre entre la réactivité et de bas frais généraux. Il peut être difficile de briser les calculs en même morceaux comme celui-ci face à la modification de la taille de données, mais vous auriez le même défi en une seule grande fonction qui a également fait d'E / S.

Ecrire un processus de travail en Python qui appelle ces 3 fonctions par ctypes. Demandez au processus de travail vérifier l'objet d'un file d'attente pour un message de l'interface graphique pour arrêter le calcul de bonne heure. Assurez-vous d'utiliser l'appel Queue.get_nowait non bloquante au lieu de Queue.get. Si le processus de travail trouve un message à quitter tôt, appelez le C nettoyer le code et retourner le résultat partiel.

Si vous êtes sur * nix enregistrer un gestionnaire de signal pour SIGUSR1 ou SIGINT dans votre programme C puis de Python utiliser os.kill pour envoyer le signal.

Vous l'avez dit:. Signaux et tuyaux

Il ne doit pas être trop complexe, mais ce sera un diable de beaucoup plus facile si vous utilisez une structure existante que si vous essayez de rouler votre propre.

scroll top