Problème d'utilisation des Threads avec lib javacomm

Problème d'utilisation des Threads avec lib javacomm - Java - Programmation

Marsh Posté le 16-06-2008 à 09:32:18    

Bonjour,
 
alors voilà j'espère que quelqu'un pourra m'aider avec ça, je dois développer en ce moment un petit programme permettant d'établir la communication entre le PC et une machine reliée sur le port série.
 
Pour cela j'utilise la librairie javacomm de sun, et les thread, le problème étant que je dois récupérer des données sur l'appareil relié, donc il faut que pendant un certain temps, le PC envoit les chaines correspondant à l'initialisation, puise attende un certain temps, puis envois ses différentes requêtes, attende un certain temps, puis envois la chaine correspondant au retour en idle mode de l'appareil.
 
Le truc c'est que j'ai réussi à gérer la connexion, une requête, la déconnexion, mais à partir du moment ou j'execute plus de chose ça devient tendu, car je joue avec des sleeps pour faire ça, et si j'ai plus ou moins de requêtes, la durée des sleep doit être proportionnelle... bref avec les sleeps c'est pas jouable, que j'utilise la méthode événementielle de javacomm ou en utilisant les flux.
 
Apparement une technique serait de créer un nouveau thread à chaque fois... quelqu'un aurait déjà fait ça?
 
Sinon j'avais pensé mettre le premier thread en pause, par exemple celui qui envoit la requête, et le faire reprendre quand l'autre à finit le traitement, mais c'est Deprecated dans l'API Java.
 
J'espère être clair, et que quelqu'un ai déjà fait un truc du genre.
 
Merci :)

Reply

Marsh Posté le 16-06-2008 à 09:32:18   

Reply

Marsh Posté le 16-06-2008 à 21:06:48    

effectivement le sleep est rarement la bonne solution.
Si je comprend bien tu es client: Tu envoie un message, et tu reçoit une réponse ?(c'est une question en fait)
 
Généralement dans les communication:  

  • soit on est séquenciel et un thread qui s'occupe de l'envoie et la reception est suffisant, en plus du thread principal,  
  • soit les messages peuvent être mélangé, et on a un thread pour l'emission, un pour la reception et le thread principal.


La communication entre threads se fait dans des queue fifo (Une queue par thread).  
 
Dans la queue, on peut mettre:

  • soit un objet compréhensible, voir une action,
  • soit le message, et laisser l'encodage décodage a une couche du thread principal


Voici un exemple de "queue" pour une communication entre thread (tu remarquera quelle est "thread safe" )
 

Code :
  1. public class FifoRxTx implements FifoRxTxInterface {
  2.     /** the len of the queue. 16 is an optimum value */
  3.     private int bufferLen = 16;
  4.     private byte[][] buffer;
  5.     private int readPtr;
  6.     private int writePtr;
  7.     //private Vector
  8.     /**
  9.      * Creates new Queue
  10.      */
  11.     public FifoRxTx() {
  12.         buffer = new byte[bufferLen][];
  13.         readPtr = 0;
  14.         writePtr = 0;
  15.     }
  16.     /**
  17.      * Creates new Queue
  18.      */
  19.     public FifoRxTx(int len) {
  20.         this.bufferLen = len + 1;
  21.         buffer = new byte[bufferLen][];
  22.         readPtr = 0;
  23.         writePtr = 0;
  24.     }
  25.     /**
  26.      * @return true if empty
  27.      */
  28.     public boolean empty() {
  29.         return (readPtr == writePtr);
  30.     }
  31.     /**
  32.      * @return true if full
  33.      */
  34.     private boolean full() {
  35.         // works only with buffer size = 16
  36.         //return (((writePtr + 1) & 15) == readPtr);
  37.         // otherwise use this (not optimized)
  38.         return (((writePtr + 1) % bufferLen) == readPtr);
  39.     }
  40.     /**
  41.      * Push an element to the queue. Note that it is a blocking call if
  42.      * the queue is full
  43.      *
  44.      * @param i
  45.      */
  46.     public synchronized void push(byte[] i) {
  47.         while (full()) {
  48.             try {
  49.                 wait();
  50.             } catch (InterruptedException e) {
  51.             }
  52.         }
  53.         if (i != null) {
  54.             buffer[writePtr] = i;
  55.             // works only with buffer size = 16
  56.             //writePtr = (writePtr + 1) & 15;
  57.             // otherwise use this (not optimized)
  58.             writePtr = (writePtr + 1) % bufferLen;
  59.         }
  60.         notifyAll();
  61.     }
  62.     /**
  63.      * return an element of the queue if present (non blocking call)
  64.      *
  65.      * @return an element or null
  66.      */
  67.     public synchronized byte[] peek() {
  68.         byte[] i = null;
  69.         if (!empty()) {
  70.             i = buffer[readPtr];
  71.             // works only with buffer size = 16
  72.             //readPtr = (readPtr + 1) & 15;
  73.             // otherwise use this (not optimized)
  74.              readPtr = (readPtr + 1) % bufferLen;
  75.             notifyAll();
  76.         }
  77.         return i;
  78.     }
  79.     /**
  80.      * Blocking call that return an element of the queue
  81.      *
  82.      * @return
  83.      */
  84.     public synchronized byte[] pop() {
  85.         while (empty()) {
  86.             try {
  87.                 wait();
  88.             } catch (InterruptedException e) {
  89.             }
  90.         }
  91.         byte[] i = buffer[readPtr];
  92.         // works only with buffer size = 16
  93.         //readPtr = (readPtr + 1) & 15;
  94.         // otherwise use this (not optimized)
  95.          readPtr = (readPtr + 1) % bufferLen;
  96.         notifyAll();
  97.         return i;
  98.     }
  99.     /**
  100.      * Wait for a message during a timeout
  101.      *
  102.      * @param timeOut time to wait
  103.      * @return the message or null
  104.      */
  105.     public synchronized byte[] pop(int timeOut) {
  106.         if (empty()) {
  107.             try {
  108.                 wait(timeOut);
  109.             } catch (InterruptedException e) {
  110.             }
  111.         }
  112.         return peek();
  113.     }
  114.     /**
  115.      * Flush the content (delete all data in it!)
  116.      */
  117.     public synchronized void flush() {
  118.         readPtr = 0;
  119.         writePtr = 0;
  120.         notifyAll();
  121.     }
  122. }


Message édité par tempo14 le 16-06-2008 à 21:10:40
Reply

Marsh Posté le 17-06-2008 à 09:35:15    

Oui j'envois un message et je reçois une réponse. Le problème là, c'est que avec les sleeps c'est trop aléatoire, en plus selon le nombre de requêtes que j'ai a effectuer il faudrait que le sleep soit de longueur différente, donc c'est pas trop gérable proprement.
 
Avec les join() aussi ça ne marche pas.
 
En gros voici le topo:
 
1 Thread emetteur
1 Thread recepteur
Le programme principal.
 
L'idée ici c'est que l'emetteur, qui envoit les requêtes à l'appareil, va creer autant de thread qu'il y a de requêtes:
 
public void run() {
  Ecouteur thread2 = new Ecouteur(idIns, pouet(), idMethode, chemin_Portserie, pContext,connex);
   
                //Ce thread sert juste pour l'initialisation
                Initi thread3 = new Initi(retBuff(), idMethode, chemin_Portserie, pContext,connex);
 
  try {
                        //On lance l'init
                        thread3.start();
   communique("B" );
   sleep(3000);
   communique("B" );
                        //Et tant que l'init est pas finie on reste dedans grace au join()
   thread3.join();
   for (int i = 201 ; i <= 210 ; i++ ) {
           communique("A" + i );
           new Thread(thread2).start();
    thread2.join();
   }
   thread2.start();
   communique("A210" );
   thread2.join();
   communique("Z" );  
   close();
  } catch (InterruptedException e) {
 
  }
 }
 
Genre là dans la boucle, l'idée est de récuperer plusieurs fois AXXX, XXX correspond à un numéro, et l'appareil doit renvoyer des résultats. Le problème c'est que la machine est connectée en 1200 bauds et que il faut lui laisser le temps de répondre. Avec les join() même problème, des fois ça insère parfaitement les 10 résultats au final, mais en bidouillant avec des sleeps et autres... Impossible de faire ça proprement et de façon sûre (qui marche à chaque fois).


Message édité par dukable le 17-06-2008 à 09:38:33
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed