132 lines
3.8 KiB
Python
132 lines
3.8 KiB
Python
|
import threading
|
||
|
import time
|
||
|
import random
|
||
|
|
||
|
class CurrentlyComputing(Exception):
|
||
|
pass
|
||
|
|
||
|
class SuccessfulOperation(Exception):
|
||
|
pass
|
||
|
|
||
|
class FailedOperation(Exception):
|
||
|
pass
|
||
|
|
||
|
|
||
|
class LocalThread(threading.Thread):
|
||
|
|
||
|
def __init__(self, id, address, orientation, transitions):
|
||
|
|
||
|
threading.Thread.__init__(self)
|
||
|
|
||
|
self.id = id
|
||
|
self.address = address
|
||
|
self.orientation = orientation
|
||
|
self.transitions = transitions
|
||
|
self.returncode = CurrentlyComputing()
|
||
|
|
||
|
def run(self):
|
||
|
print("Thread local n°{} parle depuis {} !".format(self.id, self.address))
|
||
|
self.returncode = SuccessfulOperation()
|
||
|
time.sleep(random.randint(0,3))
|
||
|
pass
|
||
|
|
||
|
|
||
|
"""
|
||
|
a = LocalThread()
|
||
|
|
||
|
Si je lance a.run()
|
||
|
|
||
|
0) a est un LocalThread. Python charge donc la liste des fonctions de LocalThread
|
||
|
|
||
|
1) on demande la fonction run() de LocalThread
|
||
|
|
||
|
2) L'instance concernée est a, on lance donc run(a)
|
||
|
"""
|
||
|
|
||
|
class User:
|
||
|
|
||
|
stop = False
|
||
|
|
||
|
|
||
|
class GreatScheduler(threading.Thread):
|
||
|
|
||
|
def __init__(self, preemption_space, arrow_list, n_thread):
|
||
|
|
||
|
threading.Thread.__init__(self)
|
||
|
|
||
|
self.preemption_space = preemption_space
|
||
|
self.arrow_list = arrow_list
|
||
|
self.n_thread = n_thread
|
||
|
self.cur_id = -1
|
||
|
|
||
|
def run(self):
|
||
|
thread_list = []
|
||
|
|
||
|
while not User.stop:
|
||
|
|
||
|
#print("--- Mesures et écoute ---")
|
||
|
#print("Espace global de préemption :\t {}".format(self.preemption_space))
|
||
|
#print("Liste des flèches :\t {}".format(self.arrow_list))
|
||
|
|
||
|
## Tirer une flêche au hasard
|
||
|
n = int(random.random()*len(self.arrow_list))
|
||
|
elected_arrow = self.arrow_list[n]
|
||
|
|
||
|
## Vérification de l'espace global de préemption autour de la flêche
|
||
|
if not(len(thread_list) >= self.n_thread) and self.preemption_space[elected_arrow[0]]:
|
||
|
print("Espace local libre à {}".format(elected_arrow[0]))
|
||
|
self.preemption_space[elected_arrow[0]] = False
|
||
|
|
||
|
## Création du thread local
|
||
|
|
||
|
self.cur_id += 1
|
||
|
|
||
|
thread_list.append(
|
||
|
LocalThread(self.cur_id,
|
||
|
elected_arrow[0],
|
||
|
elected_arrow[1],
|
||
|
TRANSITIONS_TREE
|
||
|
)
|
||
|
)
|
||
|
|
||
|
## Lancer le thread local
|
||
|
thread_list[-1].start()
|
||
|
|
||
|
for thread in thread_list:
|
||
|
if not thread.is_alive():
|
||
|
if not thread.returncode.__class__ is SuccessfulOperation:
|
||
|
if thread.returncode.__class__ is FailedOperation:
|
||
|
print("A optimiser : créer une règle")
|
||
|
else:
|
||
|
raise thread.returncode
|
||
|
print("Thread local n°{} est terminé".format(thread.id))
|
||
|
|
||
|
self.preemption_space[thread.address] = True
|
||
|
thread_list.pop(thread_list.index(thread))
|
||
|
|
||
|
## Sortie du scheduler
|
||
|
print("Attente de la fin des thread locaux")
|
||
|
|
||
|
for thread in thread_list:
|
||
|
thread.join()
|
||
|
if not thread.returncode.__class__ is SuccessfulOperation:
|
||
|
if thread.returncode.__class__ is FailedOperation:
|
||
|
print("A optimiser : créer une règle")
|
||
|
else:
|
||
|
raise thread.returncode
|
||
|
print("Thread local n°{} est terminé".format(thread.id))
|
||
|
|
||
|
|
||
|
ARROW_NUMBER = 150
|
||
|
SPACE_SIZE = 100
|
||
|
PREEMPTION_GLOBAL_SPACE = [True] * SPACE_SIZE
|
||
|
ARROW_LIST = [(random.randint(0,SPACE_SIZE - 1),0) for x in range(ARROW_NUMBER)]
|
||
|
TRANSITIONS_TREE = None
|
||
|
MAX_THREAD = 50
|
||
|
|
||
|
scheduler = GreatScheduler(PREEMPTION_GLOBAL_SPACE, ARROW_LIST, MAX_THREAD)
|
||
|
|
||
|
def test():
|
||
|
scheduler.start()
|
||
|
time.sleep(10)
|
||
|
User.stop = True
|