L’objectif de ce laboratoire est de programmer avec des appels systèmes et de regarder les comportements.
Bibliothèques C Développer un programme prime qui calcule en C le nombre de nombres premiers inférieurs ou égaux au nombre passé en argument.
$ ./prime 5 3 $ ./prime 50 15 $ ./prime 10000000 664579 Vous utiliserez l’algo suivant (crible d’Ératosthène) :
#include <math.h> long int argument; // Argument du programme long int* primes; // Tableau de nombres premiers trouvés (à allouer dans le tas et réallouer) size_t nb; // Nombre de nombres premiers trouvés for (long int i=2; i<=argument; i++) { int prime = TRUE; for (size_t k=0; k<nb; k++) { long int j = primes[k]; if (j>sqrt(i)) { break; // on trouvera plus de diviseur, inutile de continuer de chercher } if (i%j == 0) { prime = FALSE; // c'est divisible, donc pas premier break; } } if (prime) { // on enregistre et passe au nombre suivant primes[nb] = i; // Réalouer peut-etre nb++; } } print(nb); // et voila!
Remarque: n’oubliez pas, lors de l’utilisation d’appels systèmes, de traiter les cas d’erreurs.
mmap Le programme memcat qui prend en argument le fichier à projeter et en affiche le contenu. #include<stdio.h> #include<unistd.h> #include<fcntl.h> #include<sys/stat.h> #include<sys/mman.h> int main(int argc, char **argv){ if(argc != 2){ printf("usage : %s nom_fichier\n", argv[0]); return 1; } int fd, resWrite; struct stat stat; char *buf; fd = open(argv[1], O_RDONLY); if(fd == -1){ perror("open"); return 1; } if(fstat(fd, &stat) == -1){ perror("stat"); return 1; } buf = mmap(NULL, stat.
Remarque: n’oubliez pas, lors de l’utilisation d’appels système, de traiter les cas d’erreurs.
mmap L’objectif de cet exercice est de projeter un fichier en mémoire puis d’utiliser cette projection pour effectuer des opérations.
Créez un programme memcat qui prend en argument le fichier à projeter et en affiche le contenu. Note: le fichier passé en argument doit nécessairement exister; le cas échéant affichez un message d’erreur adéquat. Utilisez les appels système mmap pour projeter le fichier en mémoire et munmap pour détruire la projection.
Producteurs/consommateurs Dans le problème du producteur et consommateur, il y a un ensemble de producteurs qui ont pour travail de générer une donnée et de la mettre en attente dans une file d’attente globale. Le travail du consommateur est de récupérer cette donnée et de la consommer.
L’objectif du laboratoire est de développer plusieurs versions du programme produc_conso en vous basant sur le squelette de code ci-dessous. Ce programme prend en argument un nombre de producteurs et un nombre de consommateurs, chacun représenté par un thread.
Remarque: n’oubiez pas, lors de l’utilisation d’appels systèmes, de traiter les cas d’erreur.
Producteurs/consommateurs Le programme produc_conso avec des int comme compteurs. #include <pthread.h> #include <semaphore.h> #include <stdlib.h> #include <stdio.h> #include <unistd.h> #define MAXDONNEE 5 // Nombre maximal de données produites par chaque producteur void attendre() { int sleep_time = (rand() % 5) + 1; // int sleep_time = 1; sleep(sleep_time); } // La déclaration des deux compteurs permettant de savoir s'il y a une donnée disponible pour le consommateur et si le producteur doit produire une donnée int empty; int full; #define TAILLE_MAX 10 // Liste d'attente char liste[TAILLE_MAX][100]; int index_ecriture=0; int index_lecture=0; //Nombre de consommateurs/producteurs int nombre_produ, nombre_conso; int TOTALDONNEE; void* producteur(void *id) { int id_producteur = *((int *) id); for (int i = 0; i < MAXDONNEE; i++) { // Gestion de la disponibilité des données while (empty <= 0) { attendre(); } empty--; int j = index_ecriture; index_ecriture++; if (index_ecriture == TAILLE_MAX) index_ecriture = 0; // Génération de la donnée sprintf(liste[j], "Le producteur %d a créé la donnée %d", id_producteur, i); printf("(+) Le producteur %d a produit : \n\tLe producteur %d a créé la donnée %d\n",id_producteur ,id_producteur, i); attendre(); // Gestion de la disponibilité des données full++; } } void* consommateur(void *id) { int id_consommateur = *((int *) id); // Calcul du nombre de données à consommer pour chaque consommateur int nb_a_consommer = TOTALDONNEE / nombre_conso + (TOTALDONNEE % nombre_conso > id_consommateur); for (int i = 0; i < nb_a_consommer; i++) { // Gestion de la disponibilité des données while (full <= 0) { attendre(); } full--; int j = index_lecture; index_lecture++; if (index_lecture == TAILLE_MAX) index_lecture = 0; printf ("(-) Consommateur %d a consommé la donnée : \n\t\"%s\"\n", id_consommateur, liste[j]); // Gestion de la disponibilité des données empty++; } } int main(int argc, char** argv) { int i; if(argc == 3){ char* endptr = NULL; nombre_produ = strtol(argv[1], &endptr, 0); if (*endptr !