problème de wait sur l'exécution d'une commande java
3 réponses
Bonjour,
J'utilise Process p = Runtime.getRuntime().exec(commande,null,dir_exécution)
pour lancer une commande java dans un répertoire donné et ensuite je teste
son résultat.
Ca fonctionne (fichier de sortie créé) sauf que le test est négatif car le
processus n'est pas terminé au moment où il est fait.
J'ai donc rajouté p.waitFor() pour attendre que le processus se termine et
là il ne rend pas la main. p.wait() n'est guère mieux.
J'ai vu sur le net que c'est probablement une histoire de bufferisation mais
je ne maîtrise pas.
Il y a aussi la solution d'utiliser un Thread mais je maîtrise encore moins.
Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
Yliur
Le Fri, 30 Aug 2013 19:21:18 +0200 <meta> a écrit :
Bonjour,
J'utilise Process p > Runtime.getRuntime().exec(commande,null,dir_exécution) pour lancer une commande java dans un répertoire donné et ensuite je teste son résultat.
Ca fonctionne (fichier de sortie créé) sauf que le test est négatif car le processus n'est pas terminé au moment où il est fait.
J'ai donc rajouté p.waitFor() pour attendre que le processus se termine et là il ne rend pas la main. p.wait() n'est guère mieux.
J'ai vu sur le net que c'est probablement une histoire de bufferisation mais je ne maîtrise pas.
Il y a aussi la solution d'utiliser un Thread mais je maîtrise encore moins.
Je cherche donc un secours ici :)
Merci pour votre aide.
Il est possible qu'il faille lire les tampons de sortie de ton processus pour éviter qu'ils ne se remplisse. Donc une bidouille avec plusieurs fils d'exécution (avec Thread par exemple). Il existe aussi une méthode simplifiée avec une méthode utilitaire de java dans les versions récentes, mais j'ai oublié ce que c'est. Quelques mots-clés bien sentis dans un moteur de recherche devraient vous permettre de retrouver ça facilement, sinon je refouillerai.
Par contre je ne comprends pas bien ce que signifie "lancer une commande java" ici. Ce mécanisme sert à lancer une commande externe (par exemple un programme exécutable existant sur le système). Si le but est de lancer un traitement en parallèle, Thread/Runnable est plus simple. Encore que dans ce cas je ne vois pas bien l'intérêt d'attendre que le processus se termine, autant exécuter le code java directement.
Quel est l'objectif exact
Le Fri, 30 Aug 2013 19:21:18 +0200
<meta> a écrit :
Bonjour,
J'utilise Process p > Runtime.getRuntime().exec(commande,null,dir_exécution) pour lancer
une commande java dans un répertoire donné et ensuite je teste son
résultat.
Ca fonctionne (fichier de sortie créé) sauf que le test est négatif
car le processus n'est pas terminé au moment où il est fait.
J'ai donc rajouté p.waitFor() pour attendre que le processus se
termine et là il ne rend pas la main. p.wait() n'est guère mieux.
J'ai vu sur le net que c'est probablement une histoire de
bufferisation mais je ne maîtrise pas.
Il y a aussi la solution d'utiliser un Thread mais je maîtrise encore
moins.
Je cherche donc un secours ici :)
Merci pour votre aide.
Il est possible qu'il faille lire les tampons de sortie de ton
processus pour éviter qu'ils ne se remplisse. Donc une bidouille avec
plusieurs fils d'exécution (avec Thread par exemple). Il existe aussi
une méthode simplifiée avec une méthode utilitaire de java dans les
versions récentes, mais j'ai oublié ce que c'est. Quelques mots-clés
bien sentis dans un moteur de recherche devraient vous permettre de
retrouver ça facilement, sinon je refouillerai.
Par contre je ne comprends pas bien ce que signifie "lancer une
commande java" ici. Ce mécanisme sert à lancer une commande externe
(par exemple un programme exécutable existant sur le système). Si le
but est de lancer un traitement en parallèle, Thread/Runnable est plus
simple. Encore que dans ce cas je ne vois pas bien l'intérêt d'attendre
que le processus se termine, autant exécuter le code java directement.
Le Fri, 30 Aug 2013 19:21:18 +0200 <meta> a écrit :
Bonjour,
J'utilise Process p > Runtime.getRuntime().exec(commande,null,dir_exécution) pour lancer une commande java dans un répertoire donné et ensuite je teste son résultat.
Ca fonctionne (fichier de sortie créé) sauf que le test est négatif car le processus n'est pas terminé au moment où il est fait.
J'ai donc rajouté p.waitFor() pour attendre que le processus se termine et là il ne rend pas la main. p.wait() n'est guère mieux.
J'ai vu sur le net que c'est probablement une histoire de bufferisation mais je ne maîtrise pas.
Il y a aussi la solution d'utiliser un Thread mais je maîtrise encore moins.
Je cherche donc un secours ici :)
Merci pour votre aide.
Il est possible qu'il faille lire les tampons de sortie de ton processus pour éviter qu'ils ne se remplisse. Donc une bidouille avec plusieurs fils d'exécution (avec Thread par exemple). Il existe aussi une méthode simplifiée avec une méthode utilitaire de java dans les versions récentes, mais j'ai oublié ce que c'est. Quelques mots-clés bien sentis dans un moteur de recherche devraient vous permettre de retrouver ça facilement, sinon je refouillerai.
Par contre je ne comprends pas bien ce que signifie "lancer une commande java" ici. Ce mécanisme sert à lancer une commande externe (par exemple un programme exécutable existant sur le système). Si le but est de lancer un traitement en parallèle, Thread/Runnable est plus simple. Encore que dans ce cas je ne vois pas bien l'intérêt d'attendre que le processus se termine, autant exécuter le code java directement.
Quel est l'objectif exact
Il est possible qu'il faille lire les tampons de sortie de ton
processus pour éviter qu'ils ne se remplisse. Donc une bidouille avec plusieurs fils d'exécution (avec Thread par exemple). Il existe aussi une méthode simplifiée avec une méthode utilitaire de java dans les versions récentes, mais j'ai oublié ce que c'est. Quelques mots-clés bien sentis dans un moteur de recherche devraient vous permettre de retrouver ça facilement, sinon je refouillerai.
Par contre je ne comprends pas bien ce que signifie "lancer une commande java" ici. Ce mécanisme sert à lancer une commande externe (par exemple un programme exécutable existant sur le système). Si le but est de lancer un traitement en parallèle, Thread/Runnable est plus simple. Encore que dans ce cas je ne vois pas bien l'intérêt d'attendre que le processus se termine, autant exécuter le code java directement.
Quel est l'objectif exact
Bonsoir, merci pour votre réponse. Le but était de lancer l'exécution d'un jar dont le but é tait de créer un fichier de sortie mais cela prenait trop de temps el te processus rendait la main avant la fin de la création. J'avais donc rajouté l'attente qui du coup se bloquait. J'ai fini par trouver sur le net qu'en fait le blocage était du au fait que les sorties (standard, erreur) n'étaient pas vidées et en rajoutant des threads consommateurs (j'ai bêtement recopié l'exemple), ça a débloqué l'attente. Mais j'avoue que j'aurais aimé voir une solution n'utilisant que les Thread, pour voir car si on n'a pas déjà vu quelqu'un le faire, c'est difficile d'intuiter....
Il est possible qu'il faille lire les tampons de sortie de ton
processus pour éviter qu'ils ne se remplisse. Donc une bidouille avec
plusieurs fils d'exécution (avec Thread par exemple). Il existe aussi
une méthode simplifiée avec une méthode utilitaire de java dans les
versions récentes, mais j'ai oublié ce que c'est. Quelques mots-clés
bien sentis dans un moteur de recherche devraient vous permettre de
retrouver ça facilement, sinon je refouillerai.
Par contre je ne comprends pas bien ce que signifie "lancer une
commande java" ici. Ce mécanisme sert à lancer une commande externe
(par exemple un programme exécutable existant sur le système). Si le
but est de lancer un traitement en parallèle, Thread/Runnable est plus
simple. Encore que dans ce cas je ne vois pas bien l'intérêt d'attendre
que le processus se termine, autant exécuter le code java directement.
Quel est l'objectif exact
Bonsoir, merci pour votre réponse. Le but était de lancer l'exécution d'un
jar dont le but é tait de créer un fichier de sortie mais cela prenait trop
de temps el te processus rendait la main avant la fin de la création.
J'avais donc rajouté l'attente qui du coup se bloquait. J'ai fini par
trouver sur le net qu'en fait le blocage était du au fait que les sorties
(standard, erreur) n'étaient pas vidées et en rajoutant des threads
consommateurs (j'ai bêtement recopié l'exemple), ça a débloqué l'attente.
Mais j'avoue que j'aurais aimé voir une solution n'utilisant que les Thread,
pour voir car si on n'a pas déjà vu quelqu'un le faire, c'est difficile
d'intuiter....
Il est possible qu'il faille lire les tampons de sortie de ton
processus pour éviter qu'ils ne se remplisse. Donc une bidouille avec plusieurs fils d'exécution (avec Thread par exemple). Il existe aussi une méthode simplifiée avec une méthode utilitaire de java dans les versions récentes, mais j'ai oublié ce que c'est. Quelques mots-clés bien sentis dans un moteur de recherche devraient vous permettre de retrouver ça facilement, sinon je refouillerai.
Par contre je ne comprends pas bien ce que signifie "lancer une commande java" ici. Ce mécanisme sert à lancer une commande externe (par exemple un programme exécutable existant sur le système). Si le but est de lancer un traitement en parallèle, Thread/Runnable est plus simple. Encore que dans ce cas je ne vois pas bien l'intérêt d'attendre que le processus se termine, autant exécuter le code java directement.
Quel est l'objectif exact
Bonsoir, merci pour votre réponse. Le but était de lancer l'exécution d'un jar dont le but é tait de créer un fichier de sortie mais cela prenait trop de temps el te processus rendait la main avant la fin de la création. J'avais donc rajouté l'attente qui du coup se bloquait. J'ai fini par trouver sur le net qu'en fait le blocage était du au fait que les sorties (standard, erreur) n'étaient pas vidées et en rajoutant des threads consommateurs (j'ai bêtement recopié l'exemple), ça a débloqué l'attente. Mais j'avoue que j'aurais aimé voir une solution n'utilisant que les Thread, pour voir car si on n'a pas déjà vu quelqu'un le faire, c'est difficile d'intuiter....
Yliur
Le Mon, 2 Sep 2013 21:45:59 +0200 <meta> a écrit :
>Il est possible qu'il faille lire les tampons de sortie de ton processus pour éviter qu'ils ne se remplisse. Donc une bidouille avec plusieurs fils d'exécution (avec Thread par exemple). Il existe aussi une méthode simplifiée avec une méthode utilitaire de java dans les versions récentes, mais j'ai oublié ce que c'est. Quelques mots-clés bien sentis dans un moteur de recherche devraient vous permettre de retrouver ça facilement, sinon je refouillerai.
Par contre je ne comprends pas bien ce que signifie "lancer une commande java" ici. Ce mécanisme sert à lancer une commande externe (par exemple un programme exécutable existant sur le système). Si le but est de lancer un traitement en parallèle, Thread/Runnable est plus simple. Encore que dans ce cas je ne vois pas bien l'intérêt d'attendre que le processus se termine, autant exécuter le code java directement.
>Quel est l'objectif exact
Bonsoir, merci pour votre réponse. Le but était de lancer l'exécution d'un jar dont le but é tait de créer un fichier de sortie mais cela prenait trop de temps el te processus rendait la main avant la fin de la création. J'avais donc rajouté l'attente qui du coup se bloquait. J'ai fini par trouver sur le net qu'en fait le blocage était du au fait que les sorties (standard, erreur) n'étaient pas vidées et en rajoutant des threads consommateurs (j'ai bêtement recopié l'exemple), ça a débloqué l'attente. Mais j'avoue que j'aurais aimé voir une solution n'utilisant que les Thread, pour voir car si on n'a pas déjà vu quelqu'un le faire, c'est difficile d'intuiter....
Pour la solution sans processus complet (donc avec seulement des fils d'exécution dans le programme) : - Ce n'est possible que si le code du jar peut être utilisé depuis l'appli principale (il faut par exemple que le jar soit dans le chemin des classes de l'appli, comme les autres bibliothèques de l'application par exemple). - Il suffit d'exécuter la méthode main() de la classe principale de ce jar exécutable. - Même pas besoin de créer un fil d'exécution supplémentaire, puisque le but est juste d'attendre que ce soit terminé ;) . Un simple appel de fonction suffit.
Sinon pour créer des fils d'exécution en Java c'est très simple : - Créer une classe (même interne ou anonyme, mais pour la dernière ce n'est pas très joli à mon goût). Cette classe doit tout simplement implémenter l'interface Runnable, qui possède une unique méthode run (voir la javadoc). - Pour lancer un fil d'exécution, qui n'est jamais qu'un nouveau pointeur dans le code avec sa propre pile (la pile d'appels des fonctions par exemple), mais qui utilise le tas commun (les objets alloués par tout le monde), il suffit d'écrire quelque chose comme ça (en supposant que ma classe TraitementAsynchrone implémente Runnable) : Thread filExec = new Thread (new TraitementAsynchrone) ; filExec.start() ; - Un nouveau pointeur d'exécution est créé dans le code, mais si les deux fils (l'ancien et le nouveau) possèdent des références vers des objets communs ils peuvent tous les deux accéder à ces objets, donc attention aux accès concourants. - À la place d'implémenter Runnable, il est possible de créer une classe héritant de Thread et de redéfinir sa méthode run. Si la nouvelle classe s'appelle TraitementAsynchrone, le lancement donne ça : TraitementSynchrone filExec = new TraitementSynchrone() ; filExec.start() ;
Le Mon, 2 Sep 2013 21:45:59 +0200
<meta> a écrit :
>Il est possible qu'il faille lire les tampons de sortie de ton
processus pour éviter qu'ils ne se remplisse. Donc une bidouille avec
plusieurs fils d'exécution (avec Thread par exemple). Il existe aussi
une méthode simplifiée avec une méthode utilitaire de java dans les
versions récentes, mais j'ai oublié ce que c'est. Quelques mots-clés
bien sentis dans un moteur de recherche devraient vous permettre de
retrouver ça facilement, sinon je refouillerai.
Par contre je ne comprends pas bien ce que signifie "lancer une
commande java" ici. Ce mécanisme sert à lancer une commande externe
(par exemple un programme exécutable existant sur le système). Si le
but est de lancer un traitement en parallèle, Thread/Runnable est plus
simple. Encore que dans ce cas je ne vois pas bien l'intérêt
d'attendre que le processus se termine, autant exécuter le code java
directement.
>Quel est l'objectif exact
Bonsoir, merci pour votre réponse. Le but était de lancer l'exécution
d'un jar dont le but é tait de créer un fichier de sortie mais cela
prenait trop de temps el te processus rendait la main avant la fin de
la création. J'avais donc rajouté l'attente qui du coup se bloquait.
J'ai fini par trouver sur le net qu'en fait le blocage était du au
fait que les sorties (standard, erreur) n'étaient pas vidées et en
rajoutant des threads consommateurs (j'ai bêtement recopié
l'exemple), ça a débloqué l'attente. Mais j'avoue que j'aurais aimé
voir une solution n'utilisant que les Thread, pour voir car si on n'a
pas déjà vu quelqu'un le faire, c'est difficile d'intuiter....
Une solution simplifiée pour Java 7 est présentée ici :
http://blog.developpez.com/adiguba/p8040/java/processbuilder_redirect
Pour la solution sans processus complet (donc avec seulement des fils
d'exécution dans le programme) :
- Ce n'est possible que si le code du jar peut être utilisé depuis
l'appli principale (il faut par exemple que le jar soit dans le
chemin des classes de l'appli, comme les autres bibliothèques de
l'application par exemple).
- Il suffit d'exécuter la méthode main() de la classe principale de
ce jar exécutable.
- Même pas besoin de créer un fil d'exécution supplémentaire,
puisque le but est juste d'attendre que ce soit terminé ;) . Un
simple appel de fonction suffit.
Sinon pour créer des fils d'exécution en Java c'est très simple :
- Créer une classe (même interne ou anonyme, mais pour la dernière
ce n'est pas très joli à mon goût). Cette classe doit tout
simplement implémenter l'interface Runnable, qui possède une
unique méthode run (voir la javadoc).
- Pour lancer un fil d'exécution, qui n'est jamais qu'un nouveau
pointeur dans le code avec sa propre pile (la pile d'appels des
fonctions par exemple), mais qui utilise le tas commun (les
objets alloués par tout le monde), il suffit d'écrire quelque
chose comme ça (en supposant que ma classe TraitementAsynchrone
implémente Runnable) :
Thread filExec = new Thread (new TraitementAsynchrone) ;
filExec.start() ;
- Un nouveau pointeur d'exécution est créé dans le code, mais si
les deux fils (l'ancien et le nouveau) possèdent des références
vers des objets communs ils peuvent tous les deux accéder à ces
objets, donc attention aux accès concourants.
- À la place d'implémenter Runnable, il est possible de créer une
classe héritant de Thread et de redéfinir sa méthode run. Si la
nouvelle classe s'appelle TraitementAsynchrone, le lancement donne
ça :
TraitementSynchrone filExec = new TraitementSynchrone() ;
filExec.start() ;
La doc de la classe Thread ici par exemple :
http://docs.oracle.com/javase/6/docs/api/
Le Mon, 2 Sep 2013 21:45:59 +0200 <meta> a écrit :
>Il est possible qu'il faille lire les tampons de sortie de ton processus pour éviter qu'ils ne se remplisse. Donc une bidouille avec plusieurs fils d'exécution (avec Thread par exemple). Il existe aussi une méthode simplifiée avec une méthode utilitaire de java dans les versions récentes, mais j'ai oublié ce que c'est. Quelques mots-clés bien sentis dans un moteur de recherche devraient vous permettre de retrouver ça facilement, sinon je refouillerai.
Par contre je ne comprends pas bien ce que signifie "lancer une commande java" ici. Ce mécanisme sert à lancer une commande externe (par exemple un programme exécutable existant sur le système). Si le but est de lancer un traitement en parallèle, Thread/Runnable est plus simple. Encore que dans ce cas je ne vois pas bien l'intérêt d'attendre que le processus se termine, autant exécuter le code java directement.
>Quel est l'objectif exact
Bonsoir, merci pour votre réponse. Le but était de lancer l'exécution d'un jar dont le but é tait de créer un fichier de sortie mais cela prenait trop de temps el te processus rendait la main avant la fin de la création. J'avais donc rajouté l'attente qui du coup se bloquait. J'ai fini par trouver sur le net qu'en fait le blocage était du au fait que les sorties (standard, erreur) n'étaient pas vidées et en rajoutant des threads consommateurs (j'ai bêtement recopié l'exemple), ça a débloqué l'attente. Mais j'avoue que j'aurais aimé voir une solution n'utilisant que les Thread, pour voir car si on n'a pas déjà vu quelqu'un le faire, c'est difficile d'intuiter....
Pour la solution sans processus complet (donc avec seulement des fils d'exécution dans le programme) : - Ce n'est possible que si le code du jar peut être utilisé depuis l'appli principale (il faut par exemple que le jar soit dans le chemin des classes de l'appli, comme les autres bibliothèques de l'application par exemple). - Il suffit d'exécuter la méthode main() de la classe principale de ce jar exécutable. - Même pas besoin de créer un fil d'exécution supplémentaire, puisque le but est juste d'attendre que ce soit terminé ;) . Un simple appel de fonction suffit.
Sinon pour créer des fils d'exécution en Java c'est très simple : - Créer une classe (même interne ou anonyme, mais pour la dernière ce n'est pas très joli à mon goût). Cette classe doit tout simplement implémenter l'interface Runnable, qui possède une unique méthode run (voir la javadoc). - Pour lancer un fil d'exécution, qui n'est jamais qu'un nouveau pointeur dans le code avec sa propre pile (la pile d'appels des fonctions par exemple), mais qui utilise le tas commun (les objets alloués par tout le monde), il suffit d'écrire quelque chose comme ça (en supposant que ma classe TraitementAsynchrone implémente Runnable) : Thread filExec = new Thread (new TraitementAsynchrone) ; filExec.start() ; - Un nouveau pointeur d'exécution est créé dans le code, mais si les deux fils (l'ancien et le nouveau) possèdent des références vers des objets communs ils peuvent tous les deux accéder à ces objets, donc attention aux accès concourants. - À la place d'implémenter Runnable, il est possible de créer une classe héritant de Thread et de redéfinir sa méthode run. Si la nouvelle classe s'appelle TraitementAsynchrone, le lancement donne ça : TraitementSynchrone filExec = new TraitementSynchrone() ; filExec.start() ;