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

Linux Discussion :

Exécution concurrente


Sujet :

Linux

  1. #1
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Points : 5 360
    Points
    5 360
    Par défaut Exécution concurrente
    Bonjour,

    Je débute avec la programmation concurrente et la bibliothèque pthread. Je programme en C sous Linux Ubuntu 6.06 (GCC version 4.0.3, kernel 2.6.15 sur un pentium IV 3.2 GHz monoprocesseur). Pour commencer avec cette bibliothèque, j'ai testé un bout de code trouvé sur le site web de Emmanuel Delahaye http://emmanuel-delahaye.developpez.com/pthreads.htm :

    Code C : 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
    #include <stdio.h>
    #include <pthread.h>
     
    static void * task_a(void *p_data)
    {
    	int i;
     
    	for (i=0; i<10; i++){
    		printf("Hello world from A    (%d)\n", i);
    	}
    	(void) p_data;
    	return NULL;
    }
     
    static void * task_b(void *p_data)
    {
    	int i;
     
    	for (i=0; i<10; i++){
    		printf("Hello world from B        (%d)\n", i);
    	}
    	(void) p_data;
    	return NULL;
    }
     
    int main(void)
    {
    	pthread_t ta;
    	pthread_t tb;
     
    	puts("Main init");
     
    	pthread_create(&ta, NULL, task_a, NULL);
    	pthread_create(&tb, NULL, task_b, NULL);
     
    	#if 1
            pthread_join(ta, NULL);
    	pthread_join(tb, NULL);
    	#endif
     
    	puts("Main end");
     
    	return 0;
    }

    L'idée est ici simplement d'exécuter les tâches main(), task_a() et task_b() de manière concurrente et d'observer ce qui se passe. Voici le résultat que j'obtient:

    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
    Main init
    Hello world from A    (0)
    Hello world from A    (1)
    Hello world from A    (2)
    Hello world from A    (3)
    Hello world from A    (4)
    Hello world from A    (5)
    Hello world from A    (6)
    Hello world from A    (7)
    Hello world from A    (8)
    Hello world from A    (9)
    Hello world from B        (0)
    Hello world from B        (1)
    Hello world from B        (2)
    Hello world from B        (3)
    Hello world from B        (4)
    Hello world from B        (5)
    Hello world from B        (6)
    Hello world from B        (7)
    Hello world from B        (8)
    Hello world from B        (9)
    Main end
    Quelles que soit le nombre de répétitions de la boucle exécutée par les fonctions task_a() et task_b() (c'est à dire i=10, 100, 1000), j'obtient une exécution séquentielle des tâches. Avez-vous une idée de la raison pour laquelle je n'obtient pas une exécution concurrente des tâches dans l'exemple ci-dessus?

    Meilleures salutations et merci d'avance pour votre aide

    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  2. #2
    Membre expérimenté
    Avatar de granquet
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2005
    Messages
    1 201
    Détails du profil
    Informations personnelles :
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2005
    Messages : 1 201
    Points : 1 421
    Points
    1 421
    Par défaut
    cela depend de ton ordonnanceur ...
    essaye avec un kernel preemptif

    Citation Envoyé par emdel
    [1] En fait, la concurrence est une notion relative. Sur un système mono-processeur, l'exécution des tâches se fait selon des critères de temps (time slicing) ou de suspensions.
    click my www
    ............|___
    ...................\
    .................._|_
    ..................\ /
    ..................."

  3. #3
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Points : 5 360
    Points
    5 360
    Par défaut
    Le problème est résolu!

    Le code ci-dessous me montre que le passage d'une tâche à l'autre s'effectue, mais beaucoup plus lentement que je l'avais imaginé.

    Code C : 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
    #include <pthread.h>
    #include <stdio.h>
     
     
    void * print_xs (void *unused)
    {
        while (1)
        fputc ('x', stderr);
        (void) unused;
        return NULL;
    }
     
     
    int main (void)
    {
    	pthread_t thread_id;
     
    	pthread_create (&thread_id, NULL, &print_xs, NULL);
     
    	while (1)
    		fputc ('o', stderr);
    	return 0;
    }
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  4. #4
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Points : 5 360
    Points
    5 360
    Par défaut
    Mon kernel n'est-il pas preemptif par défaut? J'ai l'impression que l'ordonnanceur effectue la commutation entre les tâche, mais à un rythme assez lent (toutes les 5-10s), ce qui a pour conséquence de masquer l'exécution concurrente de mon premier exemple.

    Y a-t'il un moyen de règler la durée moyenne d'un time slice? Qu'entends-tu par kernel preemptif? Un kernel temps-reel à la Ingo Molnar?

    Salutations

    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    376
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 376
    Points : 402
    Points
    402
    Par défaut
    Salut,

    Ton code ne laisse aucune chance au kernel d'executer une autre thread lorsque l'une des deux est en cours d'execution.
    Ajoute un sleep () de quelques micro secondes à la fin de tes boucles et le comportement de ton soft chagera. Idem dans ton deuxième programme, ajoute un sleep dans tes while(1).
    "There are two major products that come out of Berkeley: LSD and UNIX.
    We don't believe this to be a coincidence."
    - Jeremy S. Anderson

    La FAQ Python
    Les cours et tutoriels pour apprendre Python
    Le Forum Python

  6. #6
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Points : 5 360
    Points
    5 360
    Par défaut
    Merci beaucoup,

    C'était donc juste que mon deuxième thread n'avait pas le temps de s'exécuter avec que le 1er ait terminé. J'ai ralenti l'exécution de mes boucles à l'aide de la fonction sleep() et le comportement attendu est observé. Merci pour votre aide.

    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    376
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 376
    Points : 402
    Points
    402
    Par défaut
    En effet, c'est une des bases de la prog multi-thread. Lorsque des thread bouclent indéfiniement, il faut toujours laisser à la machine la possibilité d'exécuter les autres threads/programmes en cours. Pour ce faire il faut à un moment ou un autre ne rien faire (avec sleep). En java, il y a "yield" qui est un pseudo sleep (dors si tu n'as rien d'autre à faire), mais je ne sais pas si il y a un equivalent en C.
    "There are two major products that come out of Berkeley: LSD and UNIX.
    We don't believe this to be a coincidence."
    - Jeremy S. Anderson

    La FAQ Python
    Les cours et tutoriels pour apprendre Python
    Le Forum Python

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

Discussions similaires

  1. Logiciel de gestion de version concurrente CVS
    Par Maxbenji dans le forum CVS
    Réponses: 4
    Dernier message: 04/04/2006, 13h18
  2. Réponses: 6
    Dernier message: 13/04/2005, 09h18
  3. écritures concurrentes dans un fichier
    Par djmalo dans le forum C
    Réponses: 9
    Dernier message: 06/03/2005, 01h45
  4. Réponses: 2
    Dernier message: 05/10/2004, 22h43

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