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 :

Sémaphore, traversée d'un carrefour sans feu


Sujet :

Linux

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 26
    Par défaut Sémaphore, traversée d'un carrefour sans feu
    Voici le sujet d'un exo qui porte sur les sémaphores et qui me pose quelques difficultés (j'ai dû chercher pendant bien 5h et j'ai toujours pas trouver le bon code source). Pouvez vous me donner un petit coup de pouce ? Merci d'avance
    On veut simuler la traversée d’un carrefour routier. Le carrefour est divisé en quatre quadrants. A un instant donné, une voiture peut :
    être en attente à l’une des entrées du carrefour
    être engagée dans l’un des 4 quadrants
    poursuivre sa route vers le nord, le sud, l’est ou l’ouest

    Une voiture peut effectuer 3 types de parcours, quelle que soit sa direction d’arrivée :
    type 1 : tourner à droite en traversant un seul quadrant
    type 2 : aller tout droit en traversant deux quadrants
    type 3 : tourner à gauche en respectant la priorité et en traversant 3 quadrants

    Chaque quadrant est une ressource à partager de façon exclusive entre tous les processus voiture.

    On supposera qu’il ne peut y avoir plus de 3 voitures dans le carrefour pour éviter l’interblocage, en positionnant un sens interdit

    Simuler le fonctionnement du carrefour en utilisant des sémaphores (étude de principe, explication des choix et des algorithmes, réalisation)


    Voici jusqu'où je suis arrivé (NB : c'est pas codé très proprement ) :
    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
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
     
    #include "sema.h"
    #include <stdio.h>
    #include <stdlib.h>
     
    #define NB_VOITMAX 3
    #define NB_SEM 4
     
     
    int Random (int _iMin, int _iMax)
    {
        return (_iMin + (rand () % (_iMax-_iMin+1)));
    }
     
    void traversee1(int *tabSem,int i) //Le véhicule i tourne à droite
    {
        printf("Le vehicule provenant de %d ",i);
        printf("est engage dans le quadrant %d \n",i);
        sleep(Random(1,10));
        P(tabSem[i]);
        printf("Le vehicule provenant de %d a termine de tourner et poursuit sa route \n",i);
        exit(0);
    }
    void traversee2(int *tabSem,int i, int j) //Le véhicule va tout droit de i à j
    {
        printf("Le vehicule provenant de %d ",i);
        printf("est engage dans le quadrant %d \n",i);
        sleep(5);
        P(tabSem[i]);
        printf("Le vehicule provenant de %d ",i);
        printf("quitte le quadrant %d \n",i);
     
        sleep(2);
     
        if (fork()==0)
        {
                V(tabSem[j]);
                printf("Le vehicule provenant de %d ",i);
                printf("est engage dans le quadrant %d \n",j);
                sleep(4);
                P(tabSem[j]);
                printf("Le vehicule provenant de %d a termine de tourner et poursuit sa route \n",i);
     
        }
        exit(0);
    }
    void traversee3(int *tabSem,int i, int j, int k) //Le véhicule tourne à gauche en respectant la priorité
    {
        printf("Le vehicule provenant de %d ",i);
        printf(" est engage dans le quadrant %d \n",i);
        sleep(Random(1,2));
        printf("Le vehicule provenant de %d ",i);
        printf("quitte le quadrant %d \n",i);
        P(tabSem[i]);
     
        if (fork()==0)
        {    
            V(tabSem[j]);
            printf("Le vehicule provenant de %d ",i);
            printf(" est engage dans le quadrant %d \n",j);
            sleep(Random(1,5));
            P(tabSem[j]);
            printf("Le vehicule provenant de %d ",i);
            printf(" quitte le quadrant %d \n",j);
     
            if (fork()==0)
            {
                V(tabSem[k]);
                printf("Le vehicule provenant de %d ",i);
                printf("est engage dans le quadrant %d \n",k);
                sleep(Random(1,5));
                P(tabSem[k]);
     
                printf("Le vehicule provenant de %d a termine de tourner et poursuit sa route \n",i);
     
            }
        }
     
        exit(0);
    }
     
    void creervoiture(int t)
    {
        if (fork()==0)
        {
        V(tabSem[t]);
        printf("Un vehicule arrive et s engage dans le quadrant %d)\n",t);
        exit(0);
        }
    }
     
    int main(void)
    {
        int m,i,j,n;
        int nbvoitc; //Nb voiture se présentant au carrefour
        srand(time(NULL));
        int tabSem[NB_SEM];
        printf("Debut programme \n");
        for (m=0;m<NB_SEM;m++)
        {
            tabSem[m]=sem_create(0);
        }    
        if (fork()==0)
        {
     
                nbvoitc=Random(1,NB_VOITMAX);
                int tabvoit[nbvoitc];
                for (j=0;j<nbvoitc;j++)
                {    
                    tabvoit[j]=Random(0,NB_VOITMAX);
                    creervoiture(tabvoit[j]);
                }
                printf("Total de voitures dans le carrefour %d \n",nbvoitc);
                for (n=0;n<nbvoitc;n++)
                {    
                    int y;
                    printf("Voiture %d selectionnee",tabvoit[n]);
                    switch(Random(1,3))
                    {
                    case 1:
                        traversee1(tabSem, tabvoit[n]);
                        break;
                    case 2:
                        traversee2(tabSem, tabvoit[n],tabvoit[n]+1);
                        break;
                    case 3:
                        if (tabvoit[n]>1)
                        {
                            y=0;
                        }
                        else
                        {
                            y=(tabvoit[n]+2);
                        }
                        traversee3(tabSem, tabvoit[n],tabvoit[n]+1,y);
                    break;
                    }    
                }
     
        }
     
        exit(0);
    }

  2. #2
    Membre Expert

    Profil pro
    Inscrit en
    Mars 2004
    Messages
    1 296
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 1 296
    Par défaut
    ou est le probleme ?, l erreur ?
    il manque le fichier sema.h .....

  3. #3
    Membre très actif
    Avatar de FloMo
    Homme Profil pro
    Freelance iOS
    Inscrit en
    Juillet 2004
    Messages
    726
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Deux Sèvres (Poitou Charente)

    Informations professionnelles :
    Activité : Freelance iOS
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juillet 2004
    Messages : 726
    Par défaut
    Il y a 2 types de sémaphores :
    - les POSIX <semaphore.h> qui sont à utiliser avec des threads <phtreads.h>,
    - les System V <sys/sem.h> qui sont à utiliser avec des fork() dans le cadre IPC <sys/ipc.h>.

    Après, tu adaptes en fonction de tes besoins. Perso, je suis plus pour les threads car c'est plus léger, plus rapide et tu peux plus facilement gérer ta mémoire avec.

    Maintenant, tout dépend du but de l'exercice.

    Bon courage.

    PS : Regarde du côté de "Programmation système en C sous Linux" aux éditions Eyrolles...

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 26
    Par défaut
    Il y a 2 types de sémaphores :
    - les POSIX <semaphore.h> qui sont à utiliser avec des threads <phtreads.h>,
    - les System V <sys/sem.h> qui sont à utiliser avec des fork() dans le cadre IPC <sys/ipc.h>.
    Pour les sémaphores j'utilise #include "sema.h" avec des fork() et pour synchroniser P(...) et V(...).

    Est ce que vous pouvez m'aiguiller vers une solution qui pourrait marcher avec fork() P(...) V(...), là je suis vraiment perdu pour savoir où et comment les utiliser dans cette exo

  5. #5
    Membre très actif
    Avatar de FloMo
    Homme Profil pro
    Freelance iOS
    Inscrit en
    Juillet 2004
    Messages
    726
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Deux Sèvres (Poitou Charente)

    Informations professionnelles :
    Activité : Freelance iOS
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juillet 2004
    Messages : 726
    Par défaut
    Ca ne m'a pas l'air bien complexe, mais je n'ai pas personnellement utilisé.
    Les infos suivantes ne sont donc pas forcément pertinentes.

    P() sert à tester l'accès aux données.
    V() sert à incrémenter les données.

    L'opération Pn est bloquante jusqu'à ce que le compteur du sémaphore atteigne la valeur n, puis elle diminue sa valeur. Vn incrémente en parallèle le compteur.

    Les fonctions intéressantes sont :
    semget (key_t key, int nb, int attr);
    semop (int id, struct sembuf *operation, unsigned nb);
    semctl (int id, int num, int cmd, union semun attr);

    la structure sembuf décrit les opérations :
    - sem_num : numéro du sémaphore,
    - sem_op : opération à réaliser,
    - sem_flg : attributs de l'opération.

    - Quand sem_op est positif, le compteur interne est incrémenté de la valeur indiquée et réveille le processus en attente.
    Si sembuf.sem_op = n, l'opération est Vn().
    - Quand sem_op est négatif, le compteur interne est décrémenté de la valeur indiquée et endort le processus.
    Si sembuf.sem_op = n, l'opération est Pn().
    - Quand sem_op est nul, il endort le processus jusqu'à ce que le compteur soit nul et continue l'exécution du programme. Ca sert à synchroniser les processus.

    dans sem_flag, tu peux mettre :
    - IPC_NOWAIT : opération non-bloquante,
    - SEM_UNDO : assure que le sémaphore retrouve un état normal, même en cas d'arrêt brutal du programme.

    Pour le reste, je te conseille de te tourner vers les pages de manuel Linux par exemple.

    Je ne saurais pas trop t'en dire plus. Bon courage pour la suite.

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 26
    Par défaut
    Merci pour ton aide FloMo, mais je sais déja à peu près utiliser les sémaphores, ce qui me pose problème c'est que je sais pas comment démarrer l'exo (j'ai déjà quelques idées sur comment gérer les quadrants occupés dans le carrefour lorsqu'un véhicule choisi de le traverser, mais je sais pas comment gérer l'arrivée des véhicules à l’une des entrées du carrefour)

    Serait il possible que vous m'indiquez des pistes d'algo, la manière dont vous procèderiez... surtout si c'est possible j'aimerai savoir quel code mettre lorsqu'un véhicule arrive au carrefour et également lorsqu'un véhicule réalise un des types de parcours.

    Merci d'avance

Discussions similaires

  1. Carrefour avec sémaphores
    Par ArdGuet dans le forum C
    Réponses: 2
    Dernier message: 25/08/2010, 00h42
  2. Comment récupérer le nom du fichier sans l'extension ?
    Par altahir007 dans le forum Langage
    Réponses: 16
    Dernier message: 13/11/2009, 14h20
  3. MDI sans MFC, possible ?
    Par delire8 dans le forum MFC
    Réponses: 4
    Dernier message: 17/06/2002, 08h38
  4. [Kylix] Fiches sans bordure
    Par alex dans le forum EDI
    Réponses: 4
    Dernier message: 28/04/2002, 22h19

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