Advertisement
Jobjob

Implémentation du dîner des philosophes

Jan 18th, 2014
249
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.86 KB | None | 0 0
  1. #!/bin/python
  2. # -*- coding: utf-8 -*-
  3.  
  4. ########################################################
  5. # Implémentation du problème du dîner des philosophes. #
  6. # Par Julien Delplanque                                #
  7. # Le 18/01/2014                                        #
  8. ########################################################
  9.  
  10. import thread
  11. import time
  12.  
  13. """
  14.     Cette classe représente un verrou exclusif.
  15. """
  16. class Exclusif(object):
  17.     def __init__(self):
  18.         self.valeur = False
  19.  
  20.     def __str__(self):
  21.         if self.valeur:
  22.             return "locked"
  23.         else:
  24.             return "unlocked"
  25.  
  26. """
  27.     Cette classe représente un sémaphore, nécessaire pour cette implémentation en python
  28.     car nous ne disposons pas de pointeurs.
  29. """
  30. class Semaphore(object):
  31.    
  32.     def __init__(self,v):
  33.         self.valeur = v
  34.  
  35.     def __str__(self):
  36.         return str(self.valeur)
  37.  
  38.     """
  39.         Incrémente la valeur du sémaphore.
  40.     """
  41.     def increase(self):
  42.         self.valeur += 1
  43.     """
  44.         Décrémente la valeur du sémaphore.
  45.     """
  46.     def decrease(self):
  47.         self.valeur += 1
  48.  
  49.     """
  50.         Retourne une string à partir d'une liste de Semaphore dans un format similaire à la
  51.         représentation sous forme de string d'une liste.
  52.     """
  53.     @staticmethod
  54.     def tabStr(tab):
  55.         sTab = "["
  56.         for i in range(len(tab)-1):
  57.             sTab += str(tab[i])+","
  58.         sTab += str(tab[N-1])+"]"
  59.         return sTab
  60.  
  61. """
  62.     Processus philosophe.
  63. """
  64. def philosophe(i):
  65.     while True:
  66.         ETAT[i] = "PENSE"
  67.         prendFourch(i)
  68.         ETAT[i] = "MANGE"
  69.         poseFourch(i)
  70.  
  71. """
  72.     Prendre les deux fourchettes.
  73. """
  74. def prendFourch(i):
  75.     wait(MUTEX)
  76.     ETAT[i] = "FAIM"
  77.     test(i)
  78.     signal(MUTEX)
  79.     wait(S[i])
  80.  
  81. """
  82.     Poser les deux fouchettes.
  83. """
  84. def poseFourch(i):
  85.     wait(MUTEX)
  86.     ETAT[i] = "PENSE"
  87.     test(voisinG(i))
  88.     test(voisinD(i))
  89.     signal(MUTEX)
  90.  
  91. """
  92.     Retourne l'indice du voisin de gauche du philosophe i.
  93. """
  94. def voisinG(i):
  95.     return (i+N-1)%N
  96.  
  97. """
  98.     Retourne l'indice du voisin de droite du philosophe i.
  99. """
  100. def voisinD(i):
  101.     return (i+1)%N
  102.  
  103. """
  104.     Tenter de saisir les deux fouchettes.
  105. """
  106. def test(i):
  107.     if ETAT[i] == "FAIM" and ETAT[voisinG(i)] != "MANGE" and ETAT[voisinD(i)] != "MANGE":
  108.         ETAT[i] = "MANGE"
  109.         signal(S[i])
  110.  
  111. """
  112.     Permet de d'effectuer le wait et signal de manière atomique en verrouillant l'accès
  113.     au sémaphore. Les opérations entre lock() et unlock() font donc parti de la section
  114.     critique.
  115. """
  116. def lock(e):
  117.     while e.valeur:
  118.         pass
  119.     e.valeur = True
  120.  
  121. """
  122.     Permet de d'effectuer le wait et signal de manière atomique en déverrouillant l'accès
  123.     au sémaphore. Les opérations entre lock() et unlock() font donc parti de la section
  124.     critique.
  125. """
  126. def unlock(e):
  127.     e.valeur = False
  128.  
  129. """
  130.     Permet de faire un wait sur le sémaphore s.
  131. """
  132. def wait(s):
  133.     while s.valeur <= 0:
  134.         pass
  135.     lock(EXCLUSIF)
  136.     s.decrease()
  137.     unlock(EXCLUSIF)
  138.  
  139. """
  140.     Permet de faire un signal sur le sémaphore s.
  141. """
  142. def signal(s):
  143.     lock(EXCLUSIF)
  144.     s.increase()
  145.     unlock(EXCLUSIF)
  146.  
  147. if __name__=="__main__":
  148.     MUTEX = Semaphore(1) # Sémaphore d'exclusion mutuelle.
  149.     S = [Semaphore(0),Semaphore(0),Semaphore(0),Semaphore(0),Semaphore(0)] # Liste des sémaphores.
  150.     ETAT = ["PENSE","PENSE","PENSE","PENSE","PENSE"] # Liste des états.
  151.     EXCLUSIF = Exclusif()
  152.  
  153.     assert len(S) == len(ETAT) # S'assurer que les tailles de S et et ETAT sont égales.
  154.  
  155.     N = len(S) # Le nombre de philosophes.
  156.     DELAY = 0.5 # Delay entre chaque affichage.
  157.     try:
  158.         thread.start_new_thread( philosophe, (0, ) )
  159.         thread.start_new_thread( philosophe, (1, ) )
  160.         thread.start_new_thread( philosophe, (2, ) )
  161.         thread.start_new_thread( philosophe, (3, ) )
  162.         thread.start_new_thread( philosophe, (4, ) )
  163.     except:
  164.         print "Erreur, impossible de démarrer les threads."
  165.  
  166.     while True:
  167.         print "S:        "+Semaphore.tabStr(S)
  168.         print "ETAT:     "+str(ETAT)
  169.         print "MUTEX:    "+str(MUTEX)
  170.         print "EXCLUSIF: "+str(EXCLUSIF)
  171.         print "--------------------"
  172.         time.sleep(DELAY)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement