Questions à choix multiples

Question 1. Utilisation des sémaphores

Avant d’être utilisé, un sémaphore doit être déclaré et initialisé. Après son utilisation, il doit être détruit. Parmi les séquences d’instructions ci-dessous, une seule initialise correctement un sémaphore à la valeur 1. Laquelle ?
sem_t semaphore;

sem_init(&semaphore, 0,1);

// ...

sem_destroy(&semaphore);
sem_t semaphore;

sem_init(semaphore, 1,0);

// ...

sem_destroy(semaphore);
sem_t semaphore;

sem_init(&semaphore, 1,0);

// ...

sem_destroy(&semaphore);
sem_t *semaphore;
semaphore=(sem_t *)malloc(sizeof(struct sem_t));
if (semaphore==NULL)
   error("malloc");

sem_init(semaphore, 1, 0);

// ...

sem_destroy(semaphore);
  sem_t *semaphore;
  semaphore=(sem_t *)malloc(sizeof(struct sem_t));
  if (semaphore==NULL)
     error("malloc");

  sem_init(semaphore, 1, 0);

  // ...

  sem_destroy(&semaphore);

.. comment::

   `sem_init(3)`_ prend comme troisième argument la valeur initiale du sémaphore. `sem_destroy(3)`_ prennent comme premier argument un pointeur vers une structure ``sem_t``.

Question 2. Exclusion mutuelle

Les sémaphores peuvent être utilisés tout comme les mutex pour résoudre des problèmes d’exclusion mutuelle. Parmi les extraits de programmes ci-dessous, une seule est une solution correcte au problème de l’exclusion mutuelle en utilisant des sémaphores. Laquelle ?
static sem_t semaphore;
long global=0;

int increment(int i) {
   // ...
}

void *inc(void * param) {
  for(int j=0;j<1000000;j++) {
    sem_wait(&semaphore);
    global=increment(global);
    sem_post(&semaphore);
  }
}

int main (int argc, char *argv[])  {
  pthread_t thread[NTHREADS];
  int err;

  sem_init(&semaphore, 0,1);

  for(int i=0;i<NTHREADS;i++) {
    err=pthread_create(&(thread[i]),NULL,&inc,NULL);
    if(err!=0)
      error(err,"pthread_create");
  }

  // reste non fourni
}
sem_t * semaphore;
long global=0;

int increment(int i) {
   // ...
}

void *inc(void * param) {
  for(int j=0;j<1000000;j++) {
    sem_wait(semaphore);
    global=increment(global);
    sem_post(semaphore);
  }
}

int main (int argc, char *argv[])  {
  pthread_t thread[NTHREADS];
  int err;
  semaphore=(sem_t *)malloc(sizeof(sem_t))
  if(semaphore==NULL)
    error("malloc");

  sem_init(semaphore, 0,1);

  for(int i=0;i<NTHREADS;i++) {
    err=pthread_create(&(thread[i]),NULL,&inc,NULL);
    if(err!=0)
      error(err,"pthread_create");
  }

  // reste non fourni
}
static sem_t semaphore;
long global=0;

int increment(int i) {
   // ...
}

void *inc(void * param) {
  for(int j=0;j<1000000;j++) {
    sem_wait(&semaphore);
    global=increment(global);
    sem_post(&semaphore);
  }
}

int main (int argc, char *argv[])  {
  pthread_t thread[NTHREADS];
  int err;

  sem_init(&semaphore, 0,0);

  for(int i=0;i<NTHREADS;i++) {
    err=pthread_create(&(thread[i]),NULL,&inc,NULL);
    if(err!=0)
      error(err,"pthread_create");
  }

  // reste non fourni
}
static sem_t semaphore;
long global=0;

int increment(int i) {
   // ...
}

void *inc(void * param) {
  for(int j=0;j<1000000;j++) {
    sem_post(&semaphore);
    global=increment(global);
    sem_wait(&semaphore);
  }
}

int main (int argc, char *argv[])  {
  pthread_t thread[NTHREADS];
  int err;

  sem_init(&semaphore, 0,0);

  for(int i=0;i<NTHREADS;i++) {
    err=pthread_create(&(thread[i]),NULL,&inc,NULL);
    if(err!=0)
      error(err,"pthread_create");
  }

  // reste non fourni
}
sem_t * semaphore;
long global=0;

int increment(int i) {
   // ...
}

void *inc(void * param) {
  for(int j=0;j<1000000;j++) {
    sem_wait(semaphore);
    global=increment(global);
    sem_post(semaphore);
  }
}

int main (int argc, char *argv[])  {
  pthread_t thread[NTHREADS];
  int err;
  semaphore=(sem_t *)malloc(sizeof(sem_t))
  if(semaphore==NULL)
    error("malloc");

  sem_init(semaphore, 0,0);

  for(int i=0;i<NTHREADS;i++) {
    err=pthread_create(&(thread[i]),NULL,&inc,NULL);
    if(err!=0)
      error(err,"pthread_create");
  }

  // reste non fourni
}
sem_t * semaphore;
long global=0;

int increment(int i) {
   // ...
}

void *inc(void * param) {
  for(int j=0;j<1000000;j++) {
    sem_post(semaphore);
    global=increment(global);
    sem_wait(semaphore);
  }
}

int main (int argc, char *argv[])  {
  pthread_t thread[NTHREADS];
  int err;
  semaphore=(sem_t *)malloc(sizeof(sem_t))
  if(semaphore==NULL)
    error("malloc");

  sem_init(semaphore, 0,0);

  for(int i=0;i<NTHREADS;i++) {
    err=pthread_create(&(thread[i]),NULL,&inc,NULL);
    if(err!=0)
      error(err,"pthread_create");
  }

  // reste non fourni
}

Question 3. Fonctions “thread-safe”

La plupart des fonctions de la librairie standard sont des fonctions thread-safe, c’est-à-dire des fonctions que l’on peut utiliser dans plusieurs threads distincts sans risquer de problèmes d’accès concurrent. Cependant, certaines fonctions, souvent parmi les plus anciennes, ne sont pas thread-safe. Parmi les fonctions ci-dessous, une seule est thread-safe. Laquelle ?

gettimeofday(2)

strsep(3)

getenv(3)

getopt(3)

asctime(3)

strtok(3)

strerror(3)

getopt(3)

Verifiez vos réponses