mirror of
				https://gitlab.com/klmp200/LO41.git
				synced 2025-10-31 01:03:05 +00:00 
			
		
		
		
	Voilà comment gérer ses threads comme un boss
This commit is contained in:
		| @@ -12,6 +12,7 @@ SYNCHRONIZED_GETTER(Elevator, ELEVATOR_STATE, state) | ||||
| SYNCHRONIZED_SETTER(Elevator, ELEVATOR_STATE, state) | ||||
| SYNCHRONIZED_GETTER(Elevator, int, floor) | ||||
| SYNCHRONIZED_SETTER(Elevator, int, floor) | ||||
| SETTER(Elevator, int, thread_number); | ||||
|  | ||||
| void _free__Elevator(THIS(Elevator)){ | ||||
| 	DELETE(this->passengers); | ||||
| @@ -167,6 +168,7 @@ void *runnable_Elevator(void * void_this){ | ||||
| 			printf("Ascenseur %s :  Je suis en route vers l'étage %d\n", this->name, this->target_floor); | ||||
| 		} | ||||
| 	} | ||||
| 	data->unregister_thread(data, this->thread_number); | ||||
|  | ||||
| 	return NULL; | ||||
| } | ||||
| @@ -176,22 +178,25 @@ Elevator *_init_Elevator(char * name){ | ||||
| 	new_elevator->name = strdup(name); | ||||
| 	new_elevator->passengers = NEW(List); | ||||
| 	new_elevator->target_floor = 0; | ||||
| 	new_elevator->thread_number = -1; | ||||
|  | ||||
| 	pthread_mutex_init(&new_elevator->mutex_passengers, NULL); | ||||
| 	pthread_mutex_init(&new_elevator->mutex_state, NULL); | ||||
| 	pthread_mutex_init(&new_elevator->mutex_floor, NULL); | ||||
|  | ||||
| 	LINK_ALL(Elevator, new_elevator, | ||||
| 		 runnable, | ||||
| 		 get_number_of_passengers, | ||||
| 		 get_next_passenger_stop, | ||||
| 		 can_get_inside, | ||||
| 		 remove_passenger, | ||||
| 		 add_passenger, | ||||
| 		 get_state, | ||||
| 		 set_state, | ||||
| 		 get_floor, | ||||
| 		 set_floor, | ||||
| 		 repair | ||||
| 			 runnable, | ||||
| 			 get_number_of_passengers, | ||||
| 			 get_next_passenger_stop, | ||||
| 			 can_get_inside, | ||||
| 			 remove_passenger, | ||||
| 			 add_passenger, | ||||
| 			 get_state, | ||||
| 			 set_state, | ||||
| 			 get_floor, | ||||
| 			 set_floor, | ||||
| 			 repair, | ||||
| 			 set_thread_number | ||||
| 	); | ||||
|  | ||||
| 	new_elevator->set_floor(new_elevator, 0); | ||||
|   | ||||
| @@ -21,11 +21,13 @@ typedef struct o_Elevator { | ||||
| 	PRIVATE char * name; | ||||
| 	PRIVATE int floor; | ||||
| 	PRIVATE int target_floor; | ||||
| 	PRIVATE int thread_number; | ||||
| 	PRIVATE pthread_mutex_t mutex_passengers; | ||||
| 	PRIVATE pthread_mutex_t mutex_state; | ||||
| 	PRIVATE pthread_mutex_t mutex_floor; | ||||
|  | ||||
| 	PUBLIC void * (*runnable)(void * void_this); | ||||
| 	PUBLIC void (*set_thread_number)(_THIS(Elevator), int data); | ||||
|  | ||||
| 	SYNCHRONIZE PRIVATE void (*set_state)(_THIS(Elevator), ELEVATOR_STATE var); | ||||
| 	SYNCHRONIZE PRIVATE void (*set_floor)(_THIS(Elevator), int var); | ||||
|   | ||||
| @@ -42,6 +42,13 @@ void *runnable_Passenger(void * void_this){ | ||||
| 	return NULL; | ||||
| } | ||||
|  | ||||
| void set_thread_number_Passenger(THIS(Passenger), int thread_number){ | ||||
| 	if (this->type == RESIDENT) | ||||
| 		this->resident->set_thread_number(this->resident, thread_number); | ||||
| 	if (this->type == VISITOR) | ||||
| 		this->visitor->set_thread_number(this->visitor, thread_number); | ||||
| } | ||||
|  | ||||
| void _free__Passenger(THIS(Passenger)){ | ||||
| 	free(this); | ||||
| } | ||||
|   | ||||
| @@ -23,6 +23,7 @@ typedef struct o_Passenger { | ||||
| 	PUBLIC int (*get_destination)(_THIS(Passenger)); | ||||
| 	PUBLIC void * (*runnable)(void* void_this); | ||||
| 	PUBLIC int (*compare)(void * passenger1, void * passenger2);//yeah I know, but i needed int (*) (void*, void*) | ||||
| 	PUBLIC void (*set_thread_number)(_THIS(Passenger), int thread_number); | ||||
|  | ||||
| 	DESTRUCTOR(Passenger); | ||||
| } Passenger; | ||||
|   | ||||
| @@ -11,6 +11,7 @@ GETTER(Resident, char *, name); | ||||
| GETTER(Resident, int, destination); | ||||
| GETTER(Resident, int, id); | ||||
| GETTER(Resident, int, apartment_floor); | ||||
| SETTER(Resident, int, thread_number); | ||||
|  | ||||
| void * runnable_Resident(void * void_this){ | ||||
| 	Resident * this = (Resident*) void_this; | ||||
| @@ -30,6 +31,7 @@ void * runnable_Resident(void * void_this){ | ||||
| 	else | ||||
| 		data->main_building->go_to_floor(data->main_building, this->position, this->destination, passenger); | ||||
| 	data->decrement_active_passengers(data); | ||||
| 	data->unregister_thread(data, this->thread_number); | ||||
| 	return NULL; | ||||
| } | ||||
|  | ||||
| @@ -50,13 +52,15 @@ Resident *_init_Resident(int id, char* name, int apartment_floor, int destinatio | ||||
| 	new_resident->position = new_resident->apartment_floor; | ||||
| 	new_resident->destination = destination; | ||||
| 	new_resident->passenger = NULL; | ||||
| 	new_resident->thread_number = -1; | ||||
|  | ||||
| 	LINK_ALL(Resident, new_resident, | ||||
| 		 get_name, | ||||
| 		 get_destination, | ||||
| 		 get_id, | ||||
| 		 runnable, | ||||
| 		 get_apartment_floor | ||||
| 			 get_name, | ||||
| 			 get_destination, | ||||
| 			 get_id, | ||||
| 			 runnable, | ||||
| 			 get_apartment_floor, | ||||
| 			 set_thread_number | ||||
| 	) | ||||
|  | ||||
| 	return new_resident; | ||||
|   | ||||
| @@ -9,6 +9,7 @@ | ||||
|  | ||||
| typedef struct o_Resident { | ||||
| 	PRIVATE int id; | ||||
| 	PRIVATE int thread_number; | ||||
| 	PRIVATE int apartment_floor; | ||||
| 	PRIVATE int destination; | ||||
| 	PRIVATE int position; | ||||
| @@ -20,6 +21,7 @@ typedef struct o_Resident { | ||||
| 	PUBLIC int (*get_id)(_THIS(Resident)); | ||||
| 	PUBLIC int (*get_apartment_floor)(_THIS(Resident)); | ||||
| 	PUBLIC int (*get_destination)(_THIS(Resident)); | ||||
| 	PUBLIC void (*set_thread_number)(_THIS(Resident), int data); | ||||
|  | ||||
| 	DESTRUCTOR(Resident); | ||||
| } Resident; | ||||
|   | ||||
| @@ -22,7 +22,7 @@ int call_elevator_SharedData(THIS(SharedData), int starting_floor, int destinati | ||||
| 	return 0; | ||||
| } | ||||
| void start_thread_SharedData(THIS(SharedData), void * (*thread)(void *), void * data, int thread_number){ | ||||
| 	pthread_create(&this->threads[thread_number], 0, thread, data); | ||||
| 	pthread_create(this->threads[thread_number], 0, thread, data); | ||||
| } | ||||
|  | ||||
| void start_all_threads_SharedData(THIS(SharedData)){ | ||||
| @@ -39,18 +39,25 @@ void start_all_threads_SharedData(THIS(SharedData)){ | ||||
| 			residents = this->main_building->residents; | ||||
| 			visitors = this->main_building->visitors; | ||||
| 			this->threads_nb = residents->get_size(residents) + visitors->get_size(visitors) + ELEVATOR_NB; | ||||
| 			this->threads = malloc_or_die(sizeof(pthread_t) * this->threads_nb); | ||||
| 			this->threads = malloc_or_die(sizeof(pthread_t*) * this->threads_nb); | ||||
|  | ||||
| 			for (i=0; i < this->threads_nb; i++) | ||||
| 				this->threads[i] = malloc_or_die(sizeof(pthread_t)); | ||||
|  | ||||
| 			pthread_mutex_lock(&this->mutex_active_passengers); | ||||
| 			pthread_mutex_lock(&this->mutex_threads); | ||||
| 			/* starts threading elevators */ | ||||
| 			for (i=0; i<ELEVATOR_NB; i++) | ||||
| 			for (i=0; i<ELEVATOR_NB; i++) { | ||||
| 				this->start_thread(this, this->main_building->elevators[i]->runnable, | ||||
| 								   this->main_building->elevators[i], i); | ||||
| 				this->main_building->elevators[i]->set_thread_number(this->main_building->elevators[i], i); | ||||
| 			} | ||||
|  | ||||
| 			/* starts threading visitors */ | ||||
| 			current = visitors->get_head(visitors); | ||||
| 			while (current != NULL){ | ||||
| 				this->start_thread(this, ((Visitor*)current->get_data(current))->runnable, current->get_data(current), i); | ||||
| 				((Visitor*)current->get_data(current))->set_thread_number((Visitor*)current->get_data(current), i); | ||||
| 				current = current->get_next(current); | ||||
| 				this->active_passengers++; | ||||
| 				i++; | ||||
| @@ -60,10 +67,12 @@ void start_all_threads_SharedData(THIS(SharedData)){ | ||||
| 			current = residents->get_head(residents); | ||||
| 			while (current != NULL){ | ||||
| 				this->start_thread(this, ((Resident*)current->get_data(current))->runnable, current->get_data(current), i); | ||||
| 				((Resident*)current->get_data(current))->set_thread_number((Resident*)current->get_data(current), i); | ||||
| 				current = current->get_next(current); | ||||
| 				this->active_passengers++; | ||||
| 				i++; | ||||
| 			} | ||||
| 			pthread_mutex_unlock(&this->mutex_threads); | ||||
| 			pthread_mutex_unlock(&this->mutex_active_passengers); | ||||
| 		} | ||||
| 	} | ||||
| @@ -71,8 +80,10 @@ void start_all_threads_SharedData(THIS(SharedData)){ | ||||
|  | ||||
| void wait_all_threads_SharedData(THIS(SharedData)){ | ||||
| 	int i; | ||||
| 	for (i=0; i<this->threads_nb; i++) | ||||
| 		pthread_join(this->threads[i], NULL); | ||||
| 	for (i=0; i<this->threads_nb; i++) { | ||||
| 		if (this->threads[i] != NULL) | ||||
| 			pthread_join(*this->threads[i], NULL); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| int use_call_box_SharedData(THIS(SharedData), char * resident_name){ | ||||
| @@ -83,8 +94,11 @@ void _free__SharedData(THIS(SharedData)){ | ||||
| 	int i; | ||||
| 	if (this->threads != NULL){ | ||||
| 		for (i=0; i<this->threads_nb; i++) { | ||||
| 			printf("Quitting thread %d\n", (int) this->threads[i]); | ||||
| 			pthread_kill(this->threads[i], SIGUSR1); | ||||
| 			if (this->threads[i] != NULL) { | ||||
| 				printf("Quitting thread %d\n", (int) this->threads[i]); | ||||
| 				pthread_kill(*this->threads[i], SIGUSR1); | ||||
| 			} | ||||
| 			free(this->threads[i]); | ||||
| 		} | ||||
| 		free(this->threads); | ||||
| 	} | ||||
| @@ -111,6 +125,12 @@ void decrement_active_passengers_SharedData(THIS(SharedData)){ | ||||
| 	pthread_mutex_unlock(&this->mutex_active_passengers); | ||||
| } | ||||
|  | ||||
| void unregister_thread_SharedData(THIS(SharedData), int thread_number){ | ||||
| 	pthread_mutex_lock(&this->mutex_threads); | ||||
| 	this->threads[thread_number] = NULL; | ||||
| 	pthread_mutex_unlock(&this->mutex_threads); | ||||
| } | ||||
|  | ||||
| SharedData *_get_instance_SharedData(){ | ||||
| 	static SharedData * new_shared_data = NULL; | ||||
| 	if (new_shared_data == NULL){ | ||||
| @@ -122,6 +142,7 @@ SharedData *_get_instance_SharedData(){ | ||||
| 		new_shared_data->active_passengers = 0; | ||||
|  | ||||
| 		pthread_mutex_init(&new_shared_data->mutex_active_passengers, NULL); | ||||
| 		pthread_mutex_init(&new_shared_data->mutex_threads, NULL); | ||||
|  | ||||
| 		LINK_ALL(SharedData, new_shared_data, | ||||
| 				 start_thread, | ||||
| @@ -132,7 +153,8 @@ SharedData *_get_instance_SharedData(){ | ||||
| 				 use_call_box, | ||||
| 				 call_elevator, | ||||
| 				 decrement_active_passengers, | ||||
| 				 is_active_passengers_left | ||||
| 				 is_active_passengers_left, | ||||
| 				 unregister_thread | ||||
| 		); | ||||
| 	} | ||||
| 	return new_shared_data; | ||||
|   | ||||
| @@ -12,9 +12,10 @@ | ||||
| typedef struct o_SharedData { | ||||
| 	PRIVATE int threads_nb; | ||||
| 	PRIVATE int active_passengers; | ||||
| 	PRIVATE pthread_t *threads; | ||||
| 	PRIVATE pthread_t ** threads; | ||||
| 	PRIVATE Building * main_building; | ||||
| 	PRIVATE pthread_mutex_t mutex_active_passengers; | ||||
| 	PRIVATE pthread_mutex_t mutex_threads; | ||||
|  | ||||
| 	PRIVATE void (*start_thread)(_THIS(SharedData), void * (*thread)(void *), void * data, int thread_number); | ||||
|  | ||||
| @@ -26,6 +27,7 @@ typedef struct o_SharedData { | ||||
| 	PUBLIC int (*use_call_box)(_THIS(SharedData), char * resident_name); | ||||
| 	SYNCHRONIZE PUBLIC void (*decrement_active_passengers)(_THIS(SharedData)); | ||||
| 	SYNCHRONIZE PUBLIC int (*is_active_passengers_left)(_THIS(SharedData)); | ||||
| 	SYNCHRONIZE PUBLIC void (*unregister_thread)(_THIS(SharedData), int thread_number); | ||||
|  | ||||
| 	DESTRUCTOR(SharedData); | ||||
| } SharedData; | ||||
|   | ||||
| @@ -9,6 +9,7 @@ | ||||
| GETTER(Visitor, char*, name); | ||||
| GETTER(Visitor, int, destination); | ||||
| GETTER(Visitor, int, id); | ||||
| SETTER(Visitor, int, thread_number); | ||||
|  | ||||
| void * runnable_Visitor(void * void_this){ | ||||
| 	Visitor *this = (Visitor*) void_this; | ||||
| @@ -24,6 +25,7 @@ void * runnable_Visitor(void * void_this){ | ||||
| 	printf("Visiteur %s : J'apelle à l'interphone\nVisiteur %s : J'apprends que %s habite à l'étage %d\n", this->name, this->name, this->contact_name, (this->destination = data->use_call_box(data, this->contact_name))); | ||||
| 	data->main_building->go_to_floor(data->main_building, this->position, this->destination, passenger); | ||||
| 	data->decrement_active_passengers(data); | ||||
| 	data->unregister_thread(data, this->thread_number); | ||||
| 	return NULL; | ||||
| } | ||||
|  | ||||
| @@ -44,6 +46,7 @@ Visitor *_init_Visitor(int id, char* name, char * contact_name){ | ||||
| 	new_visitor->position = 0; | ||||
| 	new_visitor->destination = -1; | ||||
| 	new_visitor->passenger = NULL; | ||||
| 	new_visitor->thread_number = -1; | ||||
|  | ||||
| 	if (contact_name != NULL) | ||||
| 		new_visitor->contact_name = strdup(contact_name); | ||||
| @@ -51,10 +54,11 @@ Visitor *_init_Visitor(int id, char* name, char * contact_name){ | ||||
| 		new_visitor->contact_name = NULL; | ||||
|  | ||||
| 	LINK_ALL(Visitor, new_visitor, | ||||
| 		 get_name, | ||||
| 		 get_destination, | ||||
| 		 get_id, | ||||
| 		 runnable | ||||
| 			 get_name, | ||||
| 			 get_destination, | ||||
| 			 get_id, | ||||
| 			 runnable, | ||||
| 			 set_thread_number | ||||
| 	); | ||||
|  | ||||
| 	return new_visitor; | ||||
|   | ||||
| @@ -9,6 +9,7 @@ | ||||
|  | ||||
| typedef struct o_Visitor { | ||||
| 	PRIVATE int id; | ||||
| 	PRIVATE int thread_number; | ||||
| 	PRIVATE char * name; | ||||
| 	PRIVATE char * contact_name; | ||||
| 	PRIVATE int position; | ||||
| @@ -19,6 +20,7 @@ typedef struct o_Visitor { | ||||
| 	PUBLIC char * (*get_name)(_THIS(Visitor)); | ||||
| 	PUBLIC int (*get_id)(_THIS(Visitor)); | ||||
| 	PUBLIC int (*get_destination)(_THIS(Visitor)); | ||||
| 	PUBLIC void (*set_thread_number)(_THIS(Visitor), int data); | ||||
|  | ||||
| 	DESTRUCTOR(Visitor); | ||||
| } Visitor; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user