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

Concurrence et multi-thread Java Discussion :

Arrêter 4 threads temporairement


Sujet :

Concurrence et multi-thread Java

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    62
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 62
    Par défaut Arrêter 4 threads temporairement
    Bonjour,

    J'ai une classe X qui etends la classe Thread. J'instancie 4 objets de ma classe X dont les threads principaux sont actifs.

    Lors d'un évenement Y, j'aimerais bloquer les 4 Threads pour les faire redémarrer plus tard.

    Quelqu'un peut-il m'aider ?

    Merci d'avance.

  2. #2
    Membre extrêmement actif Avatar de Mister Nono
    Homme Profil pro
    Ingénieur Mathématiques et Informatique
    Inscrit en
    Septembre 2002
    Messages
    2 242
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur Mathématiques et Informatique
    Secteur : Santé

    Informations forums :
    Inscription : Septembre 2002
    Messages : 2 242
    Par défaut
    Par exemple : les threads lisent un Boolean et s'arrêtent quand celui-ci change d'état.

    Pour l'arrêt :

    return;
    OU
    sleep(xxxx);
    OU
    wait(xxxx);
    OU
    ...

    Nota : Parfois le système d'exploitation (que je ne citerais pas ) plante, et tous les petits threads de la machine s'arrêtent tout seuls.

    A+

  3. #3
    Membre Expert
    Profil pro
    Fabrication GED
    Inscrit en
    Octobre 2005
    Messages
    1 405
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Fabrication GED

    Informations forums :
    Inscription : Octobre 2005
    Messages : 1 405
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
     
    while(!stopped){
       if(paused){
          this.yield(); // Cela donne la main aux autres threads.
       }
       else{
          // Les traitements lorsque le thread n'est pas en pause.
       }
    }

  4. #4
    Membre Expert
    Avatar de professeur shadoko
    Homme Profil pro
    retraité nostalgique Java SE
    Inscrit en
    Juillet 2006
    Messages
    1 257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 76
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : retraité nostalgique Java SE

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 257
    Par défaut
    sauf erreur de ma part ça ne marche pas
    (problème des copies privées de la mémoire par les threads, voir les explications sur volatile)
    est-ce que le code mis ici http://www.developpez.net/forums/sho...d.php?t=221981 dans le post 15 te conviendrait?

  5. #5
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    94
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 94
    Par défaut
    J'ai toujours fait comme iohack et jamais eû de problèmes, qu'est ce qui ne marche pas ?

  6. #6
    Membre Expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Par défaut
    Citation Envoyé par iohack
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
     
    while(!stopped){
       if(paused){
          this.yield(); // Cela donne la main aux autres threads.
       }
       else{
          // Les traitements lorsque le thread n'est pas en pause.
       }
    }
    Le yield() ne sert à rien... Il donne la main aux autres threads, mais qu'est-ce que ça change?
    "Tout programme qui fonctionne avec un yield() doit fonctionner tout aussi bien sans le yield()" (dixit mon prof de systèmes concurrents)

  7. #7
    Candidat au Club
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 5
    Par défaut
    Salut,
    Voici l'exemple que donne Sun pour remplacer l'usage des fonctions "resume" et "suspend" :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    public void run() {
            while (true) {
                try {
                    Thread.currentThread().sleep(interval);
     
                    synchronized(this) {
                        while (threadSuspended)
                            wait();
                    }
                } catch (InterruptedException e){}            
            }
        }
    }

  8. #8
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    94
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 94
    Par défaut
    Citation Envoyé par ®om
    Le yield() ne sert à rien... Il donne la main aux autres threads, mais qu'est-ce que ça change?
    "Tout programme qui fonctionne avec un yield() doit fonctionner tout aussi bien sans le yield()" (dixit mon prof de systèmes concurrents)
    Oui le programme fonctionnera également sans le yield, mais il permet quand même de redonner la main plus rapidement aux autres threads, sans le yield il y a de fortes chances que le thread continue de boucler dans le while un bon nombre de fois avant de donner la main aux autres threads.
    La le "if(paused){" est tout en haut du run ce n'est pas trop grave car une boucle va très vite mais si tu as une opération entre le while et le if, ne pas mettre de yield peut augmenter significativement le temps d'éxécution.

  9. #9
    Membre Expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Par défaut
    Citation Envoyé par Kikito
    Oui le programme fonctionnera également sans le yield, mais il permet quand même de redonner la main plus rapidement aux autres threads, sans le yield il y a de fortes chances que le thread continue de boucler dans le while un bon nombre de fois avant de donner la main aux autres threads.
    La le "if(paused){" est tout en haut du run ce n'est pas trop grave car une boucle va très vite mais si tu as une opération entre le while et le if, ne pas mettre de yield peut augmenter significativement le temps d'éxécution.
    Donc le programme ne fonctionne pas correctement sans le yield() (boucle infinie à ne rien faire)... Il est incorrect...
    C'est pour ça qu'il ne faut pas utiliser de l'attente active mais de l'attente passive... Par exemple par un moniteur ou un sémaphore...

  10. #10
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    94
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 94
    Par défaut
    Heu je n'ai pas de programme mais si le programme fonctionnerait correctement, et la boucle n'est pas infinie, mais sans le yield c'est le programme qui décide tout seul du moment où aller regarder les autres threads, ce qui peut causer une augmentation du temps d'éxécution.

    Et utiliser une sémaphore n'a pas le même but (pas sûr de ce que tu appelles un moniteur en francais), une sémaphore est à utiliser quand on ne veut pas dépasser un certain nombre de thread en simultané (l'utilisation d'un ThreadPoolExecutor est d'ailleurs plus simple), là l'intérêt du yield est de rendre la main aux autres threads tout de suite sans attendre que cela se fasse tout seul qq temps plus tard.

  11. #11
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    94
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 94
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    		ExecutorService exec = Executors.newFixedThreadPool(2);
    		exec.execute(new Thread(){
    			public void run(){
    				while(!stopped){
    					System.out.println("passe dans le while du thread 1");
    					if(paused){
    						//yield();
    					}
    				}
    			}
    		});
    		exec.execute(new Thread(){
    			public void run(){
    				stopped = true;
    			}
    		});
    		exec.shutdown();
    Sans le yield il fait 7 ou 8 prints avant de passer au second, avec le yield s'est instantané, le programme fdonnera bien le même résultat mais le yield permet quand même de gagner du temps.

  12. #12
    Membre Expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Par défaut
    Citation Envoyé par Kikito
    Heu je n'ai pas de programme mais si le programme fonctionnerait correctement, et la boucle n'est pas infinie, mais sans le yield c'est le programme qui décide tout seul du moment où aller regarder les autres threads, ce qui peut causer une augmentation du temps d'éxécution.
    Plus précisément, c'est l'ordonnanceur, qui choisit l'ordre d'exécution des threads...

    Citation Envoyé par Kikito
    Et utiliser une sémaphore n'a pas le même but (pas sûr de ce que tu appelles un moniteur en francais), une sémaphore est à utiliser quand on ne veut pas dépasser un certain nombre de thread en simultané (l'utilisation d'un ThreadPoolExecutor est d'ailleurs plus simple)
    C'est une application particulière du sémaphore... Tu peux très bien faire un sémaphore à 1 jeton pour simuler un verrou (et donc simuler une attente passive, ton "pause" prendrait le jeton et empêcherait la suite du code de s'exécuter jusqu'au "dépause")...

    Citation Envoyé par Kikito
    là l'intérêt du yield est de rendre la main aux autres threads tout de suite sans attendre que cela se fasse tout seul qq temps plus tard.
    Et l'intérêt de changer de thread courant immédiatement est?

    De plus, le yield() ne garantit pas que ça va changer de thread courant...

  13. #13
    Membre Expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Par défaut
    Citation Envoyé par Kikito
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    		ExecutorService exec = Executors.newFixedThreadPool(2);
    		exec.execute(new Thread(){
    			public void run(){
    				while(!stopped){
    					System.out.println("passe dans le while du thread 1");
    					if(paused){
    						//yield();
    					}
    				}
    			}
    		});
    		exec.execute(new Thread(){
    			public void run(){
    				stopped = true;
    			}
    		});
    		exec.shutdown();
    Sans le yield il fait 7 ou 8 prints avant de passer au second, avec le yield s'est instantané, le programme fdonnera bien le même résultat mais le yield permet quand même de gagner du temps.
    Bah oui, tu m'étonnes...
    On est dans le cas où le yield() change l'exécution du programme, et donc dans le cas où l'algorithme est mal conçu...

    En utilisant une attente passive, tu gagnerais encore du temps par rapport à ce que tu fais là, car là dans l'état !stopped && paused, à chaque fois que le thread a la main, il refait le test "if paused... while !stopped" (un certain nombre de fois).
    C'est clairement là que l'on doit utiliser une autre méthode qu'une attente active (surtout que ça doit bien bouffer du processeur)...

    PS: regarde sur mon tuto dans la section "synchronisation coopérative":
    http://rom.developpez.com/java-synchronisation/

  14. #14
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    94
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 94
    Par défaut
    Je veux bien que tu me montres comment ne pas utiliser d'attente active dans ce cas car je ne vois pas.

    D'ailleurs je suis quasi sûr que ce que tu crois être de l'attente passive est de l'attente active, la méthode wait() étant native on ne sait pas exactement ce qu'elle fait, mais pour la méthode await() de java.util.concurrent.locks.Condition ce n'est qu'une attente active masquée :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    public final void await() throws InterruptedException {
                if (Thread.interrupted()) 
                    throw new InterruptedException();
                Node node = addConditionWaiter();
                int savedState = fullyRelease(node);
                int interruptMode = 0;
                while (!isOnSyncQueue(node)) {
                    LockSupport.park();
                    if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
                        break;
                }
                if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
                    interruptMode = REINTERRUPT;
                if (interruptMode != 0)
                    reportInterruptAfterWait(interruptMode);
            }
    Et même si wait() était elle passive (j'en doute), on ne peut l'uitliser sans attente active que dans le même thread ( sinon déclenchement de l'exception thread not owner ).
    Cela mle semble donc impossible, ceci dit s'il existe un moyen ça m'intéresse vraiment de le connaitre.

    Edit: je ne parle biensûr pas des sleep() qui sont passifs mais qui ne résoudrait pas le problème ( il y aurait juste moins de passage dans la boucle avec un sleep(5) ou sleep(10) ).

  15. #15
    Membre Expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Par défaut
    Citation Envoyé par Kikito
    Je veux bien que tu me montres comment ne pas utiliser d'attente active dans ce cas car je ne vois pas.

    D'ailleurs je suis quasi sûr que ce que tu crois être de l'attente passive est de l'attente active, la méthode wait() étant native on ne sait pas exactement ce qu'elle fait, mais pour la méthode await() de java.util.concurrent.locks.Condition ce n'est qu'une attente active masquée :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    public final void await() throws InterruptedException {
                if (Thread.interrupted()) 
                    throw new InterruptedException();
                Node node = addConditionWaiter();
                int savedState = fullyRelease(node);
                int interruptMode = 0;
                while (!isOnSyncQueue(node)) {
                    LockSupport.park();
                    if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
                        break;
                }
                if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
                    interruptMode = REINTERRUPT;
                if (interruptMode != 0)
                    reportInterruptAfterWait(interruptMode);
            }
    Et même si wait() était elle passive (j'en doute), on ne peut l'uitliser sans attente active que dans le même thread ( sinon déclenchement de l'exception thread not owner ).
    Cela mle semble donc impossible, ceci dit s'il existe un moyen ça m'intéresse vraiment de le connaitre.

    Edit: je ne parle biensûr pas des sleep() qui sont passifs mais qui ne résoudrait pas le problème ( il y aurait juste moins de passage dans la boucle avec un sleep(5) ou sleep(10) ).
    Je ne sais pas où tu as eu ce code, Condition est une interface (tu as dû l'avoir dans une classe l'implémentant)...

    Cependant, je ne suis pas d'accord avec toi, ça n'est pas de l'attente active (ça n'est pas parce qu'il y a un while que c'est de l'attente active, toujours voir III.A.1 dans le tuto), Une des méthodes dans ce while est forcément passive...

    Quand tu dis "on ne peut l'utiliser sans attente active que dans le même thread", c'est faux, wait() s'applique sur n'importe quel objet, pas forcément le Thread en question...

    Voici un bout de code que je viens de faire pour montrer comment faire une attente passive pour pauser un thread, en utilisant le moniteur de la classe Object (wait() et notify()):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    public class AttentePassive {
     
        private final Object lock = new Object();
     
        private Thread thread;
     
        private boolean stopped;
        private boolean paused;
        private int i;
     
        public AttentePassive() {
            new Thread() {
     
                @Override public void run() {
                    methodThreadSepare();
                }
            }.start();
        }
     
        public void methodThreadSepare() {
            while(!stopped) {
                synchronized(lock) {
                    while(paused) {
                        try {
                            lock.wait();
                        } catch(InterruptedException e) {}
                    }
                }
                System.out.println(i++);
            }
        }
     
        public void pauseThread() {
            synchronized(lock) {
                paused = true;
            }
        }
     
        public void unpauseThread() {
            synchronized(lock) {
                paused = false;
                lock.notify();
            }
        }
     
        public void stop() {
            synchronized(lock) {
                unpauseThread();
                stopped = true;
            }
        }
     
        public static void main(String... args) {
            final AttentePassive attentePassive = new AttentePassive();
            /* On lance un robot qui à intervalles prédéfinis pause et unpause le thread (pour le test). */
            new Thread() {
                @Override public void run() {
                    try {
                        Thread.sleep(500);
                    } catch(InterruptedException e) {}
                    attentePassive.pauseThread();
                    try {
                        Thread.sleep(1500);
                    } catch(InterruptedException e) {}
                    attentePassive.unpauseThread();
                    try {
                        Thread.sleep(500);
                    } catch(InterruptedException e) {}
                    attentePassive.pauseThread();
                    try {
                        Thread.sleep(1500);
                    } catch(InterruptedException e) {}
                    attentePassive.unpauseThread();
                    try {
                        Thread.sleep(500);
                    } catch(InterruptedException e) {}
                    attentePassive.stop();
                }
            }.start();
        }
     
    }
    Il n'est pas commenté, si tu as des questions, n'hésite pas

  16. #16
    Membre Expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Par défaut
    Et avec le package java.util.concurrent au lieu du moniteur de Object (car le moniteur de Object est équivalent à un Lock limité à une seule variable condition, ici ça suffit, mais dans le cas général, ça ne suffit pas):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
     
    public class AttentePassiveConcurrent {
     
        private final Lock lock = new ReentrantLock();
        private final Condition notPaused = lock.newCondition();
     
        private Thread thread;
     
        private boolean stopped;
        private boolean paused;
        private int i;
     
        public AttentePassiveConcurrent() {
            new Thread() {
     
                @Override public void run() {
                    methodThreadSepare();
                }
            }.start();
        }
     
        public void methodThreadSepare() {
            while(!stopped) {
                lock.lock();
                while(paused) {
                    try {
                        notPaused.await();
                    } catch(InterruptedException e) {}
                }
                lock.unlock();
                System.out.println(i++);
            }
        }
     
        public void pauseThread() {
            lock.lock();
            paused = true;
            lock.unlock();
        }
     
        public void unpauseThread() {
            lock.lock();
            paused = false;
            notPaused.signal();
            lock.unlock();
        }
     
        public void stop() {
            lock.lock();
            unpauseThread();
            stopped = true;
            lock.unlock();
        }
     
        public static void main(String... args) {
            final AttentePassive attentePassive = new AttentePassive();
            /* On lance un robot qui à intervalles prédéfinis pause et unpause le thread (pour le test). */
            new Thread() {
     
                @Override public void run() {
                    try {
                        Thread.sleep(500);
                    } catch(InterruptedException e) {}
                    attentePassive.pauseThread();
                    try {
                        Thread.sleep(1500);
                    } catch(InterruptedException e) {}
                    attentePassive.unpauseThread();
                    try {
                        Thread.sleep(500);
                    } catch(InterruptedException e) {}
                    attentePassive.pauseThread();
                    try {
                        Thread.sleep(1500);
                    } catch(InterruptedException e) {}
                    attentePassive.unpauseThread();
                    try {
                        Thread.sleep(500);
                    } catch(InterruptedException e) {}
                    attentePassive.stop();
                }
            }.start();
        }
     
    }

  17. #17
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    94
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 94
    Par défaut
    Merci d'avoir pris le temps de répondre.

    Ok avec toi concernant le wait() j'ai parlé trop vite il suffit en effet d'utiliser un objet.

    Là ou je suis moins d'accord c'est concernant le while et la définition du actif, le bout de code tiré de AbstractQueuedSynchronizer.java à priori ( lu rapidement ) empeche le thread courant d'être programmer dans le temps (schedule) puis vérifie que le thread n'a pas été intérrompu en boucle, je ne considère pas ça comme une attente utile au déroulement de l'application.
    Je ne vois pas de grosses différences avec un :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    try {
        LockSupport.park();
        Thread.sleep(5); //ou même yield() qui est utile !    
    }
    catch(InterruptedException e) {}
    Donc oui c'est clair faire un await() sur une Condition c'est beaucoup plus classe et stylé et la partie non sympatique est immergé mais est-ce que ça change vraiment qq chose en terme de fonctionnement global ou de performances ? je suis moins sûr.

    Edit: et j'aimerais vérifier mais ça ne m'étonnerait vraiment pas que wait() soit juste une boucle qui attend un notify() à intervalle régulier

  18. #18
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    94
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 94
    Par défaut
    A priori après qq recherches ça semble être dans interrupt_md.c :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    while ((sig = lookupSignal()) == -1) {
            sigMonitorWait();
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    static void sigMonitorWait()
    {
        thread_t self = thr_self(); 
     
        unsigned int saved_count = userSigMon.count;
     
        sysAssert(userSigMon.owner == self);
        sysAssert(userSigMon.count > 0);
     
        userSigMon.count = 0;
        userSigMon.owner = 0;
     
        condvarWait(&userSigMon.condvar, &userSigMon.mutex, CONDVAR_WAIT);
     
        sysAssert(userSigMon.owner == 0);
        sysAssert(userSigMon.count == 0);
     
        userSigMon.count = saved_count;
        userSigMon.owner = self;
    }
    Je n'irais pas éplucher le code c de java pour savoir exactement ce que ça fait mais ça ne semble pas très passif ça fait les mêmes actions en boucle

  19. #19
    Membre Expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Par défaut
    Ca utilise simplement les primitives d'attente passive du système d'exploitation (heureusement qu'il y en a et qu'on n'est pas obligé d'utiliser de l'attente active, tu imagines?)...
    condvarWait doit être passive (vu le nom)

  20. #20
    Membre Expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Par défaut
    Citation Envoyé par Kikito
    Là ou je suis moins d'accord c'est concernant le while et la définition du actif, le bout de code tiré de AbstractQueuedSynchronizer.java à priori ( lu rapidement ) empeche le thread courant d'être programmer dans le temps (schedule) puis vérifie que le thread n'a pas été intérrompu en boucle
    Dans mon tuto, regarde ce bout de code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    class ListeTab {
     
        private String[] tab = new String[50];
        private int index = 0;
     
        synchronized void ajoute(String s) {
            tab[index] = s;
            index++;
            notify();
            System.out.println("notify() exécuté"); 
        }
     
        synchronized String getPremierElementBloquant() {
            //tant que la liste est vide
            while(index == 0) {
                try {
                    //attente passive
                    wait();
                } catch(InterruptedException ie) {
                    ie.printStackTrace();
                }
            }
            return tab[0];
        }
     
    }
    Tu ne penses pas que c'est le même type de while (qui ne tourne pas "en boucle", mais qui permet simplement de revérifier la condition une fois que l'attente passive est terminée)?

Discussions similaires

  1. Tri multi-threadé
    Par Tifauv' dans le forum C
    Réponses: 8
    Dernier message: 28/06/2007, 09h00
  2. Réponses: 5
    Dernier message: 12/06/2002, 15h12
  3. [Kylix] Pb de Thread !!
    Par Anonymous dans le forum EDI
    Réponses: 1
    Dernier message: 25/04/2002, 13h53

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