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 ?
sem_t
. sem_init(3) prend comme troisième argument la valeur initiale du sémaphore.