TD

Gestion des Sémaphores Linux en Langage C


Instructions

  • Expliquer le fonctionnement des programmes sema1.c et sema2.c

  • Puis, expliquer le fonctionnement du programme sema3.c


Programme sema1.c

/*  
 * ######
 * ## sema1.c
 * ## ~~~~~~~
 * ## 04.02.1995: Creation TL
 * ## 07.05.2018:
 * ######
 */

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>

#include <signal.h>

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <unistd.h>


/* Declaration des Types et des Variables */

  
typedef void (*sighandler_t) (int);

  
extern int errno;

  
key_t      key 3;
  
int        semidnsemssemnum;

  
struct sembuf sops;

  
union  semun {
      
int                 val;
      
struct semid_ds    *buf;
      
unsigned short int *array;
      
struct seminfo     *__buf;
  } 
arg;

/* Routine de Traitement de l'interruption SIGINT */
/* -> on arrete le programme */

void my_stop_int()
{
  
printf"\nsema1> my_stop_int : Arret du programme sans destuction du semaphore\n" );
  exit( 
);
}

/* Routine de Traitement de l'interruption SIGUSR1 */
/* -> on remet a zero la valeur du semaphore */

void my_stop_usr1()
{
  
int kr;
  
semnum  0;
  
arg.val 0;
  
  
kr semctlsemidsemnumSETVALarg );
  if ( 
kr == ) {
    
perror"\nsema1> my_stop_usr1 : Pb. initialisation SEMAPHORE\n" );
  } else {
    
printf"\nsema1> my_stop_usr1 : Remise a Zero  SEMAPHORE( 3, 0 )\n" );
  }
}

/* Routine de Traitement de l'interruption SIGUSR2 */
/* -> on supprime le semaphore et arrete le programme */

void my_stop_usr2()
{
  
int kr;
  
semnum 0;

  
kr semctl(semidsemnumIPC_RMIDNULL);
  if ( 
kr == -) {
    
perror"\nsema1> my_stop_usr2 : Pb. destruction semaphore\n" ); exit( );
  } else {
    
printf"\nsema1> my_stop_usr2 : Destruction SEMAPHORE(3)\n" );
  }
  exit( 
);
}

/* Programme principal */

int main()
{
  
int    krval;

  
char   SS1024 ];
  
char Ptr_SS = &SS];

/* Prise en compte des routines de traitement des interruptions SIGINT, SIGUSR1 et SIGUSR2 */

  /* tester sans SIGINT puis avec...*/

  /*
  signal( SIGINT , (sighandler_t) my_stop_int );
  */

  
signalSIGUSR1, (sighandler_tmy_stop_usr1 );
  
signalSIGUSR2, (sighandler_tmy_stop_usr2 );

/* Creation/attachement du groupe 3 constitue de 1 semaphore (numero zero) */
  
  
printf" sema1> Ouverture Ensemble de Semaphores ( key = 3 ) avec 1 seul semaphore\n");
  
printf" sema1> \n");

  
key   3;
  
nsems 1;

  
semid semgetkeynsems0640 IPC_CREAT );
  if ( 
semid == -) {
    
perror" sema1> Creation SEMAPHORE impossible" ); exit( );
  }

/* Affichage de la valeur associiee au semaphore zero */

  
semnum 0;
    
  
val semctlsemidsemnumGETVALNULL );
  if ( 
val == -) {
    
perror" sema1> Pb. recuperation valeur semaphore zero" );
  }

  
printf" sema1> Valeur du semaphore zero = %d\n"val );
  
printf" sema1> \n");

/* Message d'accueil  */

  
printf" sema1> Pour deverouiller la ressource, lancer sema2\n");
  
printf" sema1> Pour remettre a Zero le SEMAPHORE(3), faire kill -%d %d\n"
          
SIGUSR1getpid() );
  
printf" sema1> Pour arreter le programme, faire ^C ou bien kill -%d %d\n"
          
SIGUSR2getpid() );

/* precaution deverouillage automatique semop */

  
sops.sem_flg SEM_UNDO;

/* boucle */

  
for (;;) {
    
printf" sema1> Entrez un commentaire ----> " ); scanf"%s"Ptr_SS );
    
    
sops.sem_num =  0;    
    
sops.sem_op  = -1/* < 0 :  demande d'un droit */

    
kr semopsemid, &sops);
    if ( 
kr == -) {
      if ( 
errno == ) {
        
printf" sema1> Deblocage par signal\n" );
      } else {
        
printf" sema1> Erreur decrementation semaphore\n" );
      }
    }

    
printf" sema1> Liberation\n" );
    
printf" sema1> Echo du commentaire   - - > %s\n"Ptr_SS );

    
semnum 0;
    
    
val semctlsemidsemnumGETVALNULL );
    if ( 
val == -) {
      
perror" sema1> Pb. recuperation valeur semaphore" );
    }

    
printf" sema1> Valeur du semaphore = %d\n"val );
  }
}
/* --- fin  sema1.c  --- */

Programme sema2.c

/*  
 * ######
 * ## sema2.c
 * ## ~~~~~~~
 * ## 04.02.1995: Creation TL
 * ## 07.05.2018:
 * ######
 */

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>

#include <unistd.h>

int main()
{
  
int    semidvalnsemssemnumstatus;
  
key_t  key;
  
struct sembuf sops;
  
size_t nsops;

  
/* recuperation du groupe 3 constitue de 1 semaphore */
  
  
key   3;
  
nsems 1;
  
  
semid semget(keynsems0640 IPC_CREAT);
  if ( 
semid == -) {
    
perror" sema2> Pb. recuperation SEMAPHORE\n" ); exit( );
  }

  
nsops=( size_t nsems;
  
sops.sem_num 0;
  
sops.sem_op  1/* > 0 : donne un droit supplementaire*/
  
sops.sem_flg 0;

  
status =  semopsemid, &sopsnsops );
  if ( 
status == -) {
    
perror" sema2> Pb. incrementation SEMAPHORE\n" ); exit(2);
  }

  
semnum=0;
  
val semctl(semidsemnumGETVALNULL);
  if ( 
val == -) {
    
perror" sema2> Pb. recuperation valeur SEMAPHORE\n" );
  }

  
printf" sema2> Valeur du SEMAPHORE(3, 0) = %d\n"val );
  exit( 
);

}
/* ---  fin  sema2.c  --- */

Programme sema3.c

/*  
 * ######
 * ## sema3.c
 * ## ~~~~~~~
 * ## 12.02.2013: Creation T
 * ## 07.05.2018:
 * ######
 */

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/signal.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <unistd.h>

/* Declaration des Types et des Variables */

  
extern int errno;

/* Programme principal */

int main()
{
  
key_t  key 3;

  
int    semidnsemssemnum;
  
int    krval;

  
int    b_EXISTS 0;

/* Attachement Ensemble( 3 ) qui est constitue de 1 semaphore */
  
  
printf" sema3> \n");
  
printf" sema3> Tentative Ouverture Ensemble SEMAPHORES( 3 ) avec IPC_EXCL\n");
  
printf" sema3> \n");

  
nsems 1;

  
semid semgetkeynsems0640 IPC_CREAT IPC_EXCL );

  if ( 
semid == -) {
    if ( 
errno == EEXIST ) {

      
b_EXISTS 1;

      
printf" sema3> Ensemble de SEMAPHORES( 3 ) existant \n");
      
printf" sema3> \n");

      
/* Re-ouverture sans IPC_EXCL */

      
semid semgetkeynsems0640 IPC_CREAT );

      
/* Affichage de la valeur associee au semaphore numero 0 */

      
semnum 0;
    
      
val semctlsemidsemnumGETVALNULL );

      if ( 
val == -) {

        
perror" sema3> Pb. recuperation valeur semaphore" );

      } else {

        
printf" sema3> Valeur du semaphore zero = %d\n"val );
      }

      
printf" sema3> \n");

    } else {

      
perror" sema3> Pb. Ouverture Ensemble SEMAPHORES( 3 )" ); exit( );
      
printf" sema3> \n");
    }

  } else {

    
printf" sema3> Ensemble SEMAPHORES( 3 ) inexistant\n" );
    
printf" sema3> \n");
  }

/* Destruction de l'ensemble de semaphores ( 3 ) */

  
semnum 0;

  
kr semctl(semidsemnumIPC_RMIDNULL);

  if ( 
kr == -) {
    
perror" sema3> Pb. destruction semaphore\n" ); exit( );
    
printf" sema3> \n");

  } else if ( 
b_EXISTS ) {

    
/* Affichage du message seulment si il existait avant */ 

    
printf" sema3> Destruction SEMAPHORE(3)\n" );
    
printf" sema3> \n");
  }
}
/* --- fin  sema3.c  --- */

Makefile pouvant être utilisé pour la génération des exécutables