#include #include #include #include #include #include #include pthread_key_t key; pthread_once_t once_control; void init_routine() { int ret = pthread_key_create(&key, NULL); assert(!ret); } /* Implémentation maison de la fonction strtok * A la différence de strtok, my_strtok considère que le délimiteur est * constitué d'un seul caractère. */ char* my_strtok_r(char* str, const char delim, char**saveptr) { int ret = pthread_once(&once_control, init_routine); assert(!ret); int *cur_pos_ptr = pthread_getspecific(key); if(!cur_pos_ptr) { /* premiere invocation */ cur_pos_ptr = malloc(sizeof(int)); assert(cur_pos_ptr); *cur_pos_ptr=0; pthread_setspecific(key, cur_pos_ptr); } int cur_pos = *cur_pos_ptr; char*s = NULL; if(str){ *saveptr = str; s=str; cur_pos=0; } else { s = *saveptr; } int start_pos =cur_pos; int end_pos = -1; /* supprime les delimiteurs au debut de la chaine s */ for( ; s[cur_pos] != '\0' && s[cur_pos] == delim; cur_pos++) { } /* cur_pos indique le debut du token */ start_pos = cur_pos; for(; s[cur_pos] != '\0' && s[cur_pos] != delim; cur_pos++) { /* ne rien faire */ } end_pos = cur_pos;// end_pos indique la position du délimiteur (ou de '\0') if(start_pos == end_pos) { /* aucun token n'a été trouvé */ *cur_pos_ptr = cur_pos; return NULL; } /* extracttion du token */ int len = end_pos - start_pos; assert(len>=0); char* res = malloc(sizeof(char)*(1+len)); assert(res); res = strncpy(res, &s[start_pos], len); res[len] = '\0'; assert(res); *cur_pos_ptr = cur_pos; return res; } char**args = NULL; /* semaphore utilisé pour indiquer que le thread a récupéré son paramètre */ sem_t sem_ready; void* extract_tokens(void* arg) { int my_id = *(int*)arg; int ret = sem_post(&sem_ready); assert(!ret); char* str = args[my_id+1]; /* extraction du premier token */ char*saveptr = NULL; char*s = my_strtok_r(str, ':', &saveptr); printf("[%d] '%s'\n", my_id, s); /* extraction des tokens suivants */ while(s) { free(s); s = my_strtok_r(NULL, ':', &saveptr); if(s) printf("[%d] '%s'\n", my_id, s); } free(s); return NULL; } int main(int argc, char**argv) { int ret = 0; if(argc<2) { fprintf(stderr, "Usage: %s param1 ...\n", argv[0]); fprintf(stderr, "please provide at least one parameter\n"); return EXIT_FAILURE; } args = argv; ret = sem_init(&sem_ready, 0, 0); assert(!ret); /* crée un thread par paramètre * chaque thread est chargé d'extraire les tokens situés dans son paramètre */ pthread_t *tids = malloc(sizeof(pthread_t)*(argc-1)); assert(tids); int i; for(i=0; i