Bonjour Andnotor et bonjour à Médinoc (pour la 4ème question),
Un grand merci pour avoir bien voulu répondre à mon appel.
Simplement pour découvrir l'utilisation des API's Windows, j'ai choisi de reprendre une petite application que j'avais proposée, sous LINUX, à la demande d'un professeur de mathématiques pour préfacer à l'époque des programmes écrits en fortran et/ou en Basic par ses élèves lors de travaux pratiques. J'en ai fait une description sur mon site "ICI". D'ailleurs, par la suite, une esquisse avait été commencée, malheureusement non concrétisée, suivant le même principe, pour un professeur de technologie, dans le but de préfacer des programmes d'élèves afin de piloter une petite fraiseuse à commandes numériques connectées avec une ligne série plutôt que de saisir manuellement des interminables commandes en G-code ISO sur un terminal Newburry connecté à la machine.
1°) - Comment détecter dans le processus-père que le processus-fils n'existe plus ?
Effectivement, vous m'avez mis la puce à l'oreille en me suggérant que je libérais prématurément mes Handles et plus particulièrement, celui du PROCESS_INFORMATION. Désolé, j'avoue humblement être passé dessus à maintes reprises sans y prêter attention comme un débutant même si j'étais préoccupé à apprendre à me servir de ces API's et.... il y en a à apprendre !...
Comme vous me l'avez proposé, j'ai donc ouvert un thread supplémentaire qui ne contient qu'un appel à la fonction "WaitForSingleObject(process_info.hProcess, INFINITE)" suivi d'un drapeau d'alerte pour le programme processus-père. J'avais tenté d'utiliser cette fonction dans la boucle "GetMessage(...)" sans y parvenir.
D'ailleurs, petite réflexion toute personnelle, pourquoi les fonctions "WaitForSingleObject(..)" et "WaitForMultipleObjects(...)" avec un timeout de 0 ne retournent-elles pas un code du type par exemple "WAIT_CHILD_TERMINATED" ? On pourrait alors les utiliser dans la boucle "GetMessage()", beaucoup plus simplement, me semble-t-il, que de lancer un thread, solution qui ne doit pas être anodine au niveau du système.
Mais bon ... il faut faire avec !...
2°) - Comment le processus-père peut-il forcer le processus-fils à terminer son exécution ?
En effet, la question rejoignait la première et le "TerminateProcess(process_info.hProcess, 9999)" s'est alors mis à bien fonctionner.
Vous dites que la fonction "TerminateProcess()" est brutale. Mais quand un met fin à l'activité d'un programme, c'est une action brutale. Renvoyant un code retour, elle me paraît moins brutale qu'un abort avec un code d'erreur. non ?
Est-elle proscrite par les développeurs des API's ?
3°) - Comment programmer le dialogue processus-père <=> processus-fils pour que le processus-père sache que le processus-fils réclame une saisie sur le clavier ?
Effectivement, j'ai abandonné la méthode que j'avais trouvée sur la toile. J'ai scinder le dialogue en une fonction réception et une fonction transmission chacune dans deux threads différents qui se synchronisent tous seuls par le comportement de l'utilisateur.
Mon application comporte maintenant 4 threads :
- le thread du processus-père,
- le thread de réception des données en provenance du processus-fils
- le thread de transmission des données clavier vers le processus-fils
- le thread de surveillance de l'activité du processus-fils.
Elle a l'air de se comporter à peu près correctement, pour le moment tout au moins.
Reste la dernière question !...
4°) - Par quel moyen le processus-père peut-il forcer le processus-fils à effectuer des entrées/sorties NON bufferisées ?
Le langage C, pour ne prendre que lui, emmagasine les données dans un buffer avant de les envoyer sur la console. Ceci me gêne car cela oblige les programmeurs, en C par exemple, à coder un "fflush(stdout)" avant chaque lecture ce que j'aurais bien aimé éviter.
Mais, il doit être néanmoins possible de forcer ces entrées/sorties car le debugger "gdb" y arrive si on debugue un programme C qui exécute plusieurs "printf" avant de lire sur le clavier.
Quand au logigramme, avec les dernières modifications, il s'est singulièrement simplifié, et dans la logique, et dans la réalisation.
Je vous renouvelle mes remerciements pour votre aide d'autant plus que je viens de faire un petit essai de curiosité.
Jusqu'à présent, je lançait la commande (les '_' étant des valeurs par défaut) :
ng_apiptgr _ _ _ _ _ _ lissajous_F
pour encapsuler le programme fortran de tracé de courbes de "Lissajous".
J'ai tenté la commande :
ng_apiptgr _ _ _ _ _ _ gdb --args lissajous_F
pour encapsuler le programme "gdb" qui encapsule à son tour le programme fortran "lissajous_F". Mon programme semble avoir bien réagi au premier abord en capturant les i/o du gdb. Cela me permettra peut-être de faire une petite évaluation sur la programmation d'un programme qui analyse le dialogue de "gdb" pour le rendre interactif avec les curses par exemple comme le font les produits UNIX "cgdb", "xdbx", "ddd".
Bien cordialement.
Lou Papet
Partager