IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Java Discussion :

Lancer plusieurs instances d'un programme, partageant les mêmes ressources


Sujet :

Java

  1. #1
    Nouveau membre du Club
    Inscrit en
    Août 2007
    Messages
    43
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 43
    Points : 31
    Points
    31
    Par défaut Lancer plusieurs instances d'un programme, partageant les mêmes ressources
    Bonjour,

    Je travaille actuellement sur un outil permettant de convertir un ensemble de fichiers images, contenu dans un même dossier, vers un autre format d'image dans un autre dossier (ou le même...). Le programme serait lancé en tâche de fond et exécute de manière périodique son code, qui traiterait ainsi les nouveaux fichiers ajoutés entre n et n+1

    Le métier du programme est codé et fonctionne à merveille, pour une instance. Néanmoins, j'aimerais pouvoir lancer plusieurs instances de ce programme sur la même machine (voire plusieurs machines, plus tard) afin que le traitement de fasse de manière parallèle et la problématique étant bien sûr que les différentes instances ne doivent pas traiter le même fichier, ni les fichiers déjà traités.

    J'utilise pour l'instant un Timer et une classe dérivant de TimerTask.

    Quelqu'un aurait-il une solution à me proposer ?

    Merci?

  2. #2
    Membre régulier
    Inscrit en
    Janvier 2011
    Messages
    51
    Détails du profil
    Informations forums :
    Inscription : Janvier 2011
    Messages : 51
    Points : 71
    Points
    71
    Par défaut
    Je pense qu'il est facilement possible de gèrer le problème avec une db.

    Plus explicitement: tu nourris ta bd en spécifiant quel fichier a été traité, est traité ou est en attente de traitement. De cette manière, tu peux avoir autant d'instance que tu le désires, il n'y aura pas de conflits.

  3. #3
    Nouveau membre du Club
    Inscrit en
    Août 2007
    Messages
    43
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 43
    Points : 31
    Points
    31
    Par défaut
    Oui, j'y ai aussi pensé. Malheureusment, je n'ai pas le droit d'en utiliser une. Du coup, la seule solution que j'ai trouvé pour le moment est un fichier texte dans lequel j'ajoute le nom des fichiers traités à chaque fois, mais cette solution n'est pas forcément fiable et est surtout très couteuse en temps car le programme doit reconsulter l'intégralité du fichier à chaque itération de la boucle...

    Du coup, je cherche toujours une solution optimale.

  4. #4
    Membre chevronné
    Inscrit en
    Août 2009
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Août 2009
    Messages : 1 073
    Points : 1 806
    Points
    1 806
    Par défaut
    Tu ne peux pas faire bouger tes fichiers ? Ou bien créer des fichiers .lock vides ?

    Cela dit, fais attention car avec ce genre de méthode, on prend toujours le risque de conflits !

  5. #5
    Membre éclairé Avatar de Heimdal
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    549
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 549
    Points : 718
    Points
    718
    Par défaut
    Pourquoi ne pas simplement faire du multi-threading?

  6. #6
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    La base de donnée partagée est la seule solution pratique si tu veux faire du multi-machines. Les .lock c'est bien joli mais souvent ça se casse les dents sur des dossiers réseau (seul des dossiers locaux peuvent donner des garanties sur la création de fichiers lock). Un alternative, ce serait d'avoir toutes tes application qui discuttent, par exemple, en multicast sur le réseau pour savoir qui fait quoi, mais c'est se tapper le travail d'implémentation d'un sémaphore distribué, bonne chances.

    Maintenant, si tu travaille dans une seule machine, je vois pas l'intéret de lancer plusieurs JVMs plutot que de faire du multi-thread dans une seule

    Après il reste les solutions approximative: si pas de .lock ou si .lock "vieux", on le crée et on fait le traitement, en acceptant que occasionellement 2 process traitent le même fichier.

  7. #7
    Expert éminent sénior
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Points : 12 977
    Points
    12 977
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    Maintenant, si tu travaille dans une seule machine, je vois pas l'intéret de lancer plusieurs JVMs plutot que de faire du multi-thread dans une seule
    Pour des histoire d'optimisation de l'utilisation des ressources système (sur des systèmes multi-coeur, multi proc assez bourrins, pas sur que ce soit le cas ici) il est de temps en temps préférable d'avoir N JVM de taille moyenne tournant qu'une méga JVM over threadée. En effet l'ordonnanceur de l'OS gère de façon différente les process et le threads (Sinon quel intérêt aux clusters verticaux?)
    Hey, this is mine. That's mine. All this is mine. I'm claiming all this as mine. Except that bit. I don't want that bit. But all the rest of this is mine. Hey, this has been a really good day. I've eaten five times, I've slept six times, and I've made a lot of things mine. Tomorrow, I'm gonna see if I can't have sex with something.

  8. #8
    Membre régulier
    Inscrit en
    Janvier 2011
    Messages
    51
    Détails du profil
    Informations forums :
    Inscription : Janvier 2011
    Messages : 51
    Points : 71
    Points
    71
    Par défaut
    Citation Envoyé par Bash01 Voir le message
    Oui, j'y ai aussi pensé. Malheureusment, je n'ai pas le droit d'en utiliser une. Du coup, la seule solution que j'ai trouvé pour le moment est un fichier texte dans lequel j'ajoute le nom des fichiers traités à chaque fois, mais cette solution n'est pas forcément fiable et est surtout très couteuse en temps car le programme doit reconsulter l'intégralité du fichier à chaque itération de la boucle...

    Du coup, je cherche toujours une solution optimale.
    Pour quelle raison tu n'as pas le droit d'utiliser une db? Je suis vraiment curieux de savoir...

    Sinon pour le fichier, tu n'es pas obligé de tout stocker dans un seul fichier mais dans plusieurs en utilisant la logique que tu désires pour optimiser les accès.

    Si tu es obligé d'utiliser un seul fichier, alors il vaut mieux selon moi écrire un programme indépendant qui se charge sur demande des instances que tu lances, de lire et de nourrir le fichier.

  9. #9
    Nouveau membre du Club
    Inscrit en
    Août 2007
    Messages
    43
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 43
    Points : 31
    Points
    31
    Par défaut
    Citation Envoyé par SamSer Voir le message
    Pour quelle raison tu n'as pas le droit d'utiliser une db? Je suis vraiment curieux de savoir...
    Juste parce que c'est une application d'entreprise et que je n'ai pas le droit de toucher à leur BD existante ou en créer une autre pour l'utiliser. Quand il s'agit de grosse boîte, généralement on n'a pas trop le droit de toucher au SI existant...

    Sinon merci pour les solutions, je sais qu'aucune d'entre elles ne garantit un résultat 100% fiable, mais c'est déjà mieux que ma solution...

  10. #10
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    on a pas dit que tu devais "installer" une base de donnée, il existe suffsament de bases de données pur java (HSQLDB, Derby, H2, SQLIte) ne necessitant pas de maintenance pour que ca n'affecte pas leur SI et que ça soit considéré comme faisant partie de ton application

  11. #11
    Nouveau membre du Club
    Inscrit en
    Août 2007
    Messages
    43
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 43
    Points : 31
    Points
    31
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    on a pas dit que tu devais "installer" une base de donnée, il existe suffsament de bases de données pur java (HSQLDB, Derby, H2, SQLIte) ne necessitant pas de maintenance pour que ca n'affecte pas leur SI et que ça soit considéré comme faisant partie de ton application
    Non, en fait le problème est plus profond que cela. A vrai dire, je n'ai pas le droit d'utiliser des outils, frameworks ou librairies tiers non validée par l'entreprise, et je sais que ces derniers ne le seront pas. En gros, j'ai le droit d'utiliser Java 6, et c'est tout...

    Mais sinon, au final j'ai adopté une solution plus simple qui consiste à renommer les fichiers en ajoutant le préfixe "_done" (et les renommer à la fin par leur nom original). Mais par contre, je ne comprends pas pourquoi j'ai des erreurs d'accès concurrents lorsque je lance plusieurs instances du programme...

    Voici le début du bout de code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    for(String fileName : sourceFiles){
    	File f = new File(sourceFolderPath + System.getProperty("file.separator") + fileName);
    	if(f.exists() && f.renameTo(new File(sourceFolderPath + System.getProperty("file.separator") + "_done_" + fileName))){
    Si je ne me trompe pas, seul un seul processus peut entrer dans cette condition, non ? Comment cette erreur peut-elle se produire ?

    Une des solutions que j'ai trouvé pour le moment est de faire un Collections.shuffle sur sourceFiles. Cela diminue grandement le risque d'accès concurrents, mais ne l'enlève pas.

  12. #12
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    ben non, si t'as 15 programme qui font le même test en même temps, tu va avoir 15 programme qui vont avoir true à f.exists() et ces 15 mêmes programmes qui vont tenter le rename

    Une solution potable serait plutot:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    String progId = UUID.randomUUID().toString();
    for(String fileName : sourceFiles){
    	File f = new File(sourceFolderPath + System.getProperty("file.separator") + fileName);
    	if(f.exists()){ 
              File newFile=new File(sourceFolderPath + System.getProperty("file.separator") + "_done_"+progId + fileName);
              f.renameTo(newFile)
              if (newFile.exists()){
                 //ok il est à nous
              }

    De toutes façons, ce genre de code sera bancal dès que tu utilisera des disques réseau avec ton programme sur plusieurs machines. Et même en local t'aura encore des fichiers qui passeront les mailles du filet.

    Mettre en place des verrous partagés entre plusieurs applications, c'est loin d'être une mince affaire.

    Maintenant, au lieu de passer par une base de donnée tu peux aussi écrire ton propre serveur qui ferait le dispatching entre les différentes instance des fichiers à traiter. Genre une socket où tu demande le fichier suivant à traiter et ton te renvoie le nom....

    Sincères condoléances pour les limitations dans les librairies, j'adore les société qui se tirent dans les pieds avec des règles pareilles

  13. #13
    Nouveau membre du Club
    Inscrit en
    Août 2007
    Messages
    43
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 43
    Points : 31
    Points
    31
    Par défaut
    OK, merci beaucoup !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Comment empêcher de lancer plusieurs instances d'un programme?
    Par homeostasie dans le forum Code::Blocks
    Réponses: 1
    Dernier message: 28/10/2008, 21h14
  2. Réponses: 1
    Dernier message: 22/11/2007, 17h15
  3. Réponses: 7
    Dernier message: 09/10/2007, 15h26
  4. [Info] lancer plusieurs instances d'Eclipse
    Par soeursourire dans le forum Eclipse Java
    Réponses: 4
    Dernier message: 08/03/2006, 16h42

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo