#include #include #include #include #include #include #include /* Q3.b : nombre de threads traitant les jobs */ #define MAX_PARALLEL_JOBS 4 /* nombre de jobs à traiter */ #define NJOBS 40 /* fichier dans lequel doivent être écrits les résultats */ #define FILE_NAME "results.dat" /* calcule le resultat du job 'job_id' */ #define RESULT(job_id) (((job_id)+17)%13) struct job_t { int job_id; /* identifiant du job */ int res; /* resultat du job */ struct job_t *next; /* pointeur vers le job suivant */ }; /* pointeur vers le premier job de la liste */ struct job_t *jobs = NULL; /* A COMPLETER: * déclarer les éventuelles variables globales */ int fd; pthread_t tids[MAX_PARALLEL_JOBS]; sem_t job_ready; pthread_mutex_t job_list; /* protege l'acces à la liste */ pthread_mutex_t mutex_fichier; /* protege l'acces au fichier */ /* traite un job */ void process_job(struct job_t*j) { printf("Processing job %d\n", j->job_id); usleep(10000*j->job_id); j->res = RESULT(j->job_id); } /* enregistre le résultat d'un job dans le fichier */ void save_result(struct job_t*j) { /* Q3.a: A COMPLETER * ecrire j->res au bon endroit dans le fichier */ pthread_mutex_lock(&mutex_fichier); off_t ret = lseek(fd, j->job_id*sizeof(int), SEEK_SET); assert(ret == j->job_id*sizeof(int)); int ret_write = write(fd, &j->res, sizeof(int)); assert(ret_write == sizeof(int)); pthread_mutex_unlock(&mutex_fichier); } /* traiter les jobs soumis */ void traiter_jobs() { while(1) { /* on prend un job de la liste */ struct job_t*j = jobs; if(jobs) { jobs = jobs->next; } else { /* il n'y a plus de job à traiter. On s'arrête */ return; } /* on traite le job j, et on enregistre le résultat */ process_job(j); save_result(j); free(j); } } void* thread_func(void* arg) { int ret; while(1) { /* on prend un job de la liste */ ret = sem_wait(&job_ready); assert(ret == 0); pthread_mutex_lock(&job_list); struct job_t*j = jobs; if(jobs) { jobs = jobs->next; } else { /* il n'y a plus de job à traiter. On s'arrête */ pthread_mutex_unlock(&job_list); return NULL; } pthread_mutex_unlock(&job_list); /* on traite le job j, et on enregistre le résultat */ process_job(j); save_result(j); free(j); } return NULL; } /* initialise le traitement des jobs */ void init_workers() { /* Q3.a: A COMPLETER * ouvrir le fichier FILE_NAME */ fd = open(FILE_NAME, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR|S_IWUSR); assert(fd>0); int ret; ret = sem_init(&job_ready, 0, 0); assert(ret == 0); ret = pthread_mutex_init(&job_list, NULL); assert(ret == 0); ret = pthread_mutex_init(&mutex_fichier, NULL); assert(ret == 0); int i; for(i=0; ijob_id = n; j->res = -1; pthread_mutex_lock(&job_list); j->next = jobs; jobs = j; pthread_mutex_unlock(&job_list); } /* vérifie que le fichier résultat contient les bon résultats */ void check_result() { /* NE PAS MODIFIER CETTE FONCTION */ int i; int fd = open(FILE_NAME, O_RDONLY); assert(fd>0); printf("\nChecking file integrity...\n"); for(i=0; i