[ALG3IR Java] Threads && Ordonnancement

Voir le sujet précédent Voir le sujet suivant Aller en bas

resolu [ALG3IR Java] Threads && Ordonnancement

Message  galaeron le Ven 04 Jan 2013, 21:27

Bonjour/bonsoir,

Pour commencer : joyeux noël et bonne année !
Ma question porte sur les threads, en effet, je dispose à l'heure actuel de deux threads devant s'exécuter de front, l'un envois des informations sur le réseau tandis que l'autre, en récupère.

Voici une partie du code de l'un des deux threads :
Code:
while (callInProgress) {
                datagramSocket.receive(packet);
                lBytesRead += packet.getLength();
                System.out.println("Debug - AudioReceiver.java - bytesWritten " + lBytesRead);
                buffer = packet.getData();             
                sourceDataLine.write(buffer, 0, buffer.length);     
                Thread.yield();
            }

Le problème est que l'ordonnanceur favorise systématiquement un thread, provoquant la déconnexion de l'autre thread via Time Out. J'aurais donc voulu savoir si j'ai loupé une étape ou si il existe un moyen de faire ça plus proprement.

D'avance merci !


Dernière édition par galaeron le Dim 13 Jan 2013, 22:22, édité 2 fois

galaeron

Nombre de messages : 113
Age : 28
Prénom : Arthur
Statut : 3IR12
Date d'inscription : 29/06/2011

Revenir en haut Aller en bas

resolu Re: [ALG3IR Java] Threads && Ordonnancement

Message  nvs le Ven 04 Jan 2013, 21:47

ceci ?






bounce

_________________

nvs

Nombre de messages : 5238
Age : 44
Prénom : Nicolas
Statut : prof
Localisation : bxl
Date d'inscription : 24/11/2005

http://nvansteenkiste.googlepages.com

Revenir en haut Aller en bas

resolu Re: [ALG3IR Java] Threads && Ordonnancement

Message  galaeron le Ven 04 Jan 2013, 22:23

Ne semble pas fonctionner =/
Déjà l'année passée pour le cours SYS2 les "setPriority" définis par l'utilisateur n'étaient pas vraiment efficace :<

galaeron

Nombre de messages : 113
Age : 28
Prénom : Arthur
Statut : 3IR12
Date d'inscription : 29/06/2011

Revenir en haut Aller en bas

resolu Re: [ALG3IR Java] Threads && Ordonnancement

Message  pbt le Sam 05 Jan 2013, 00:35

je ne sais pas si c'est utile de faire un yield. une lecture étant bloquante, l'ordonnanceur passera au thread suivant lorsqu'il n'y a rien a lire … et il n'y a pas de timeout à ce niveau là.

_________________
smartq.namok.be · faq ·  · IRC / irc.freenode.net #esi · blog.namok.be
style #pbt {heigth:189cm; weight:79kg; eye-color:#524000; hair:very short; dead pixels: some; }

pbt
Admin

Nombre de messages : 4862
Age : 45
Prénom : Pierre
Statut : prof
Localisation : La cité des géants
Date d'inscription : 24/11/2005

http://esi.namok.be

Revenir en haut Aller en bas

resolu Re: [ALG3IR Java] Threads && Ordonnancement

Message  FûT le Sam 05 Jan 2013, 17:09

Si tu ne veux rester qu'en "local" (127.0.0.1) en travaillant sur le même processus, il y a un moyen bcp plus propre de transmettre du son (ou tout autre flux) entre différentes étapes de "traitement"; les Piped[Input|Output]Stream ! J'en avais utilisé pour créer des "Modules" que je chaînais et qui se relayais un signal MIDI ou Audio ! ;-)

Petit exemple avec deux threads: http://www.java2s.com/Code/JavaAPI/java.io/PipedOutputStreamwriteintb.htm
Code:
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;

public class Main {
  public static void main(String args[]) {
    Thread thread1 = new Thread(new PipeOutput("Producer"));
    Thread thread2 = new Thread(new PipeInput("Consumer"));
    thread1.start();
    thread2.start();
    boolean thread1IsAlive = true;
    boolean thread2IsAlive = true;
    do {
      if (thread1IsAlive && !thread1.isAlive()) {
        thread1IsAlive = false;
      }
      if (thread2IsAlive && !thread2.isAlive()) {
        thread2IsAlive = false;
      }
    } while (thread1IsAlive || thread2IsAlive);
  }
}

class PipeIO {
  PipedOutputStream outputPipe = new PipedOutputStream();

  PipedInputStream inputPipe = new PipedInputStream();
  String name;

  public PipeIO(String id) {
    name = id;
    try {
      outputPipe.connect(inputPipe);
    } catch (IOException ex) {
      System.out.println("IOException in static initializer");
    }
  }
}

class PipeOutput extends PipeIO implements Runnable {
  public PipeOutput(String id) {
    super(id);
  }

  public void run() {
    String s = "This is a test.";
    try {
      for (int i = 0; i < s.length(); ++i) {
        outputPipe.write(s.charAt(i));
        System.out.println(name + " wrote " + s.charAt(i));
      }
      outputPipe.write('!');
    } catch (IOException ex) {
      System.out.println("IOException in PipeOutput");
    }
  }
}

class PipeInput extends PipeIO implements Runnable {
  public PipeInput(String id) {
    super(id);
  }

  public void run() {
    boolean eof = false;
    try {
      while (!eof) {
        int inChar = inputPipe.read();
        if (inChar != -1) {
          char ch = (char) inChar;
          if (ch == '!') {
            eof = true;
            break;
          } else
            System.out.println(name + " read " + ch);
        }
      }
    } catch (IOException ex) {
      System.out.println("IOException in PipeOutput");
    }
  }
}

FûT

Nombre de messages : 118
Age : 26
Prénom : Raphaël
Statut : Etudiant en 3ième indu
Date d'inscription : 10/10/2010

http://ittricks.be

Revenir en haut Aller en bas

resolu Re: [ALG3IR Java] Threads && Ordonnancement

Message  galaeron le Sam 05 Jan 2013, 19:55

pbt a écrit:je ne sais pas si c'est utile de faire un yield. une lecture étant bloquante, l'ordonnanceur passera au thread suivant lorsqu'il n'y a rien a lire … et il n'y a pas de timeout à ce niveau là.
Corrigé pour optimisation mais ne résous pas le problème =/

FûT a écrit:Si tu ne veux rester qu'en "local" (127.0.0.1) en travaillant sur le même processus, il y a un moyen bcp plus propre de transmettre du son (ou tout autre flux) entre différentes étapes de "traitement"; les Piped[Input|Output]Stream ! J'en avais utilisé pour créer des "Modules" que je chaînais et qui se relayais un signal MIDI ou Audio ! ;-)
Pas mal merci ! Mais malheureusement c'est de la VOIP =')

galaeron

Nombre de messages : 113
Age : 28
Prénom : Arthur
Statut : 3IR12
Date d'inscription : 29/06/2011

Revenir en haut Aller en bas

resolu Re: [ALG3IR Java] Threads && Ordonnancement

Message  FûT le Mar 08 Jan 2013, 00:31

Bon du coup, plan B; petit coup de pouce de notre ami Mehmet Gencer: http://www.cs.bilgi.edu.tr/~mgencer/Ders%20Malzemeleri/IThingTaggedFile/MusicBroadcast.java

Bonne continuation !

Code:
/*
 * Simplistic Java music  broadcasting over UDP, where server and client are threads of the same process.
 * For a better working program, one would need to figure out how to transfer Audio file format to client.
 * Author : Mehmet Gencer, mgencer@cs.bilgi.edu.tr
 * Date: 2010
 *
*/

import java.net.*;
import java.io.*;
import java.util.*;
import javax.sound.sampled.*;
import javax.sound.sampled.AudioSystem.*;
import javax.sound.sampled.DataLine.*;

class MPListener implements Runnable{
    private static final int BUFFER_SIZE=500000;
    private int port;
    private DatagramSocket socket;
    private File outfile;
    public MPListener(int port, File outfile) {
        this.port=port;
        this.outfile=outfile;
    }
    public void run() {
        FileOutputStream stream=null;
        try {
            stream=new FileOutputStream(outfile);
            socket=new DatagramSocket(port);
            socket.setSoTimeout(10000);//wait ten seconds to start
            socket.setReceiveBufferSize(BUFFER_SIZE);
            byte[] receiveBuffer=new byte[BUFFER_SIZE];
            while(true) {
                DatagramPacket receivePacket=new DatagramPacket(receiveBuffer, receiveBuffer.length);
                try {
                    socket.receive(receivePacket);
                } catch (SocketTimeoutException e) {
                    System.out.println("Broadcast seems to have been stopped");
                    stream.close();
                    break;
                }
                stream.write(receiveBuffer,receivePacket.getOffset(),receivePacket.getLength());
                socket.setSoTimeout(500);//be less patient once started
            }
   } catch(Exception e) {
       System.out.println(String.format("MPListener error : %s",e));
            e.printStackTrace();
       return;
   }
    }
}

class MPlayer  implements Runnable{
    private MPListener mplistener;
    private File infile;
    private FileInputStream instream;
    SourceDataLine dataLine;
    private static final int BUFFER_SIZE = 500000;
    public MPlayer (MPListener mpl, File infile) {
   this.mplistener=mpl;
        this.infile=infile;
    }

    public void run() {
        System.out.println("Listener has started");
   try {
            //instream=new FileInputStream(infile);
            int c=0;
            while (infile.length()<10000 &&c++<100)
                Thread.currentThread().sleep(100);
            AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(infile);
            AudioFormat audioFormat = audioInputStream.getFormat();
            Info info = new Info(SourceDataLine.class, audioFormat);
            dataLine = (SourceDataLine) AudioSystem.getLine(info);
            dataLine.open(audioFormat, BUFFER_SIZE);
            dataLine.start();
            int readBytes = 0;
            byte[] buffer=new byte[BUFFER_SIZE];
            while (readBytes != -1) {
      readBytes = audioInputStream.read(buffer, 0,
                                                  buffer.length);
      if (readBytes >= 0)
          dataLine.write(buffer, 0, readBytes);
       }
   } catch (SocketTimeoutException e) {
            System.out.println("Broadcast seems to have been stopped");
            dataLine.stop();
        } catch(Exception e) {
       System.out.println(String.format("Listener error : %s",e));
            e.printStackTrace();
            dataLine.stop();
       return;
   }
    }
}

class Broadcaster {
    DatagramSocket socket;
    int port;
    String filename;
    Broadcaster(String filename,DatagramSocket socket,int port){
        this.socket=socket;
        this.port=port;
        this.filename=filename;
    }
    void broadcast() {
        try {
            InetAddress broadcastAddress=InetAddress.getByName("255.255.255.255");
            socket.setBroadcast(true);
            File file=new File(filename);
            int EXTERNAL_BUFFER_SIZE = 1500;
            AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(file);
            AudioFormat audioFormat = audioInputStream.getFormat();
            Info info = new Info(SourceDataLine.class, audioFormat);
           
            // opens the audio channel
            //SourceDataLine dataLine = (SourceDataLine) AudioSystem.getLine(info);
            http://dataLine.open(audioFormat, EXTERNAL_BUFFER_SIZE);
            http://dataLine.start();
           
            int readBytes = 0;
            byte[] buffer = new byte[EXTERNAL_BUFFER_SIZE];
           
            while (readBytes != -1) {
                readBytes = audioInputStream.read(buffer, 0,
                                                  buffer.length);
                DatagramPacket packet=new DatagramPacket(buffer,buffer.length,broadcastAddress,port);
                socket.send(packet);
                http://System.out.println("Sent packet");
                Thread.currentThread().sleep(8);
               
            }
            http://dataLine.stop();
        }catch(Exception e) {
            System.out.println(String.format("Announcer error : %s",e));
            e.printStackTrace(System.out);
            System.exit(0);
        }
    }     
}

public class MusicBroadcast {
    public static void main(String[] args){
        if (args.length<1) {
            System.out.println("Usage:\n MusicBroadcast mode port wavfile");
            System.out.println("  mode: 0 server, 1 player");
            System.exit(0);
        }
        int mode=Integer.parseInt(args[0]);
        int port=Integer.parseInt(args[1]);
        String filename=null;
        if (args.length>2) {
            filename=args[2];
        }
        try{
            if (mode==1) {
                File tempfile=File.createTempFile("mplayer",".wav");
                MPListener listener=new MPListener(port,tempfile);
                MPlayer player=new MPlayer(listener,tempfile);
                Thread lthread=new Thread(listener);
                lthread.start();
                Thread pthread=new Thread(player);
                pthread.start();
            }else
                new Broadcaster(filename,new DatagramSocket(),port).broadcast();
        }catch(Exception e) {}
         
    }
}

FûT

Nombre de messages : 118
Age : 26
Prénom : Raphaël
Statut : Etudiant en 3ième indu
Date d'inscription : 10/10/2010

http://ittricks.be

Revenir en haut Aller en bas

resolu Re: [ALG3IR Java] Threads && Ordonnancement

Message  galaeron le Mar 08 Jan 2013, 01:11

Merci de ton coup de main !
Il semblerait qu'il n'y ai pas de solutions miraculeuse ... En effet ma logique semble identique à celle de Mehmet Gencer à la différence que lui effectue un
Code:
Thread.currentThread().sleep(8);
une fois un paquet envoyé à la place de mon
Code:
this.yield();
. Cette méthode présente l'avantage de garantir une plus grande probabilité de succès mais aucune garantie.

J'ai donc pensé à réimplémenter quelques fonctions afin de simuler le mode connecté du tcp et de détecter d'éventuelles coupures dans le but de relancer la conversation automatiquement mais cela semble un plus difficile que prévu et le temps commence à devenir une contrainte ... La solution de facilité serait évidement d'utiliser du tcp directement et de profiter du mode connecté ... Mais cela serait alourdir inutilement l'application à nos yeux.


Dernière édition par galaeron le Mar 08 Jan 2013, 12:20, édité 1 fois

galaeron

Nombre de messages : 113
Age : 28
Prénom : Arthur
Statut : 3IR12
Date d'inscription : 29/06/2011

Revenir en haut Aller en bas

resolu Re: [ALG3IR Java] Threads && Ordonnancement

Message  FûT le Mar 08 Jan 2013, 02:43

galaeron a écrit:Merci de ton coup de main !
De rien, j'apprends aussi en même temps ;-)
galaeron a écrit:Il semblerait qu'il n'y ai pas de solutions miraculeusement ...
Quoi que.. un dernier indice et tu devrais trouver la solution ; vive stackoverflow !!!! http://stackoverflow.com/questions/2687238/java-multithreading-udp-socket-programming

FûT

Nombre de messages : 118
Age : 26
Prénom : Raphaël
Statut : Etudiant en 3ième indu
Date d'inscription : 10/10/2010

http://ittricks.be

Revenir en haut Aller en bas

resolu Re: [ALG3IR Java] Threads && Ordonnancement

Message  galaeron le Jeu 10 Jan 2013, 15:04

Problème "résolu".

Le temps avançant et n'ayant pas trouvé de solution alternative propre et fonctionnelle (certes l'executor fonctionne mais il ne résous pas le problème). J'ai utilisé une variation de la méthode de "Mehmet Gencer" qui semble fonctionner correctement à savoir Thread::sleep(long).

Merci du coup de main !



PS : @FûT Si le code t'intéresse fais moi signe !

galaeron

Nombre de messages : 113
Age : 28
Prénom : Arthur
Statut : 3IR12
Date d'inscription : 29/06/2011

Revenir en haut Aller en bas

resolu Re: [ALG3IR Java] Threads && Ordonnancement

Message  FûT le Jeu 10 Jan 2013, 18:49

galaeron a écrit:PS : @FûT Si le code t'intéresse fais moi signe !
Je t'ai envoyé un petit MP ! ;-) Merci à toi !

FûT

Nombre de messages : 118
Age : 26
Prénom : Raphaël
Statut : Etudiant en 3ième indu
Date d'inscription : 10/10/2010

http://ittricks.be

Revenir en haut Aller en bas

resolu Re: [ALG3IR Java] Threads && Ordonnancement

Message  Contenu sponsorisé Aujourd'hui à 18:58


Contenu sponsorisé


Revenir en haut Aller en bas

Voir le sujet précédent Voir le sujet suivant Revenir en haut


 
Permission de ce forum:
Vous ne pouvez pas répondre aux sujets dans ce forum