---
# System prepended metadata

title: Programmation évenementielle

---

# Programmation évenementielle

https://home.mis.u-picardie.fr/~utard/dokuwiki/doku.php

login : isri
mdp : isri1920



Solution chat python with socket 
https://home.mis.u-picardie.fr/~utard/dokuwiki/doku.php?id=m1

## Cours thread 

Support cours : https://home.mis.u-picardie.fr/~utard/dokuwiki/doku.php?id=thread

Définition : plusieurs fils d'éxécution éxécuté en même temps

Création d'une boucle pour faire tourner un thread

```
import time

def compterebour(n):
	while n>0:
		print('T moins',n)
		n -=1
		time.sleep(5)
```

Création de threads lancant un compte à rebour en utilisant la 

```

from threading import Thread

t1=Thread(target=compterebour,args=(5,))
#args=(5,)) = nuplet avec max 5 argument
t2=Thread(target=compterebour,args=(15,))

#lancement des threads
t1.start()
t2.start()

#Attendre la fin du thread précedent
t1.join()
t2.join()


```

VOIR /home/isri/documents/Prog Event/Td2/ ...py
                                       
                                        
                                        
## Cours 3 - vendredi 18 octobre - Multi Threading

Rappel cours : 

Les Threads partagent la mémoire et sont constitué de plusieurs processus

### Classe Event : 

```
from threading import Thread, Event
>>> import time
>>> e=Event()
>>> def bar():
...     while True:
...         e.wait()
...         print("GET CHEVALED")
...         e.clear()
... 
>>> 
>>> s=Thread(target=bar)
>>> s.start()
>>> e.set()
>>> GET CHEVALED

```
#### Fonction utilisé (voir exemple): 

`e.wait` 
qui attend l'événement

`e.set `

qui émet l'événement.
`clear`
qui remet l'événement à zéro.


### Classe lock

Exemple simple d'utilisation des locks

```
import threading
import time
lock=threading.Lock()
def foo():
    while True:
        print("Je prend le lock")
        lock.acquire()
        print ("J'ai pris le lock")
        time.sleep(15)
        lock.release()
        print ("J'ai relaché le lock")
        time.sleep(15)


t=threading.Thread(target=foo)
t.start()


```

*Exercice : Afficher un message lorsqu'on utilise la fonction "release()" :*

from threading import Thread,Lock
import time
l=Lock()
def toto(message):
    while True:
        l.acquire()
        print("message")
        time.sleep(5)
        l.release()
        time.sleep(5)

t=Thread(target=toto,args=("Get Chevaled",))
t.start()

//Pour l'arrêter : l.acquire


#### Fonction utilisé 


`acquire()`
qui permet à un seul thread de continuer, les autres sont bloqués 
`release()` 
qui rend le lock, et permet à un autre thread d'acquérir le lock() 

### Classe Condition

Combinaison de la classe event et de la classe Lock

#### Fonction utilisé

acquire()
release()
wait()
notify() / notifyAll()

acquire-> prendre le lock
wait -> il manque un élément, je redonne la main et je m'arrête /!\ Attente
notify-> dit au threads d'attendre

```
from threading import Thread,Condition

c=Condition()
s=0

def un():
    global s
    c.acquire()
    while (s!=1):
        c.wait()
    print("Un")
    s=2
    c.notifyAll()
    c.release()

def deux():
    global s
    c.acquire()
    while (s!=2):
    	c.wait()
    print("Deux")
    s=3
    c.notifyAll()
    c.release()

def trois():
    global s
    c.acquire()
    while (s!=3):
    	c.wait()
    print("Trois")
    s=4
    c.notifyAll()
    c.release()


t1=Thread(target=un)
t2=Thread(target=deux)
t3=Thread(target=trois)

t1.start()
t2.start()
t3.start()

c.acquire()
s=1
c.notifyAll()
c.release()
```
Au démarrage, les 3 threads vérifie s, passent en "wait" et attendant un signal
S=1 + NotifyAll -> vérification de la condition s=? par les threads
Def "un" s'applique et S=2 etc, etc.. fin



## Exercices

### Producteurs/Consommateurs


Code condition : 


from threading import *
import time

c=Condition()

class File:
    def __init__(self,n):
        self.taille=n
        self.i=0
        self.file=[]
    def put(self,value):
        if self.i==self.taille:
            raise ValueError("File pleine !")
        self.file.append(value)
        self.i=self.i+1
    def get(self):
        if self.i==0:
            raise ValueError("File vide !")
        self.i=self.i-1
        return self.file.pop(0)

def producteur(laFile):
    while True:
        c.acquire()
        while (laFile.i == laFile.taille):
            c.wait()
        laFile.put(1)
        print(laFile.i)
        time.sleep(2)
        c.notify_all()
        c.release()

def consommateur(laFile):
    while True:
        c.acquire()
        while(laFile.i == 0):
            c.wait()
        laFile.get()
        print(laFile.i)
        time.sleep(2)
        c.notify_all()
        c.release()

f=File(3)

t1=Thread(target=producteur,args=(f, ))
t2=Thread(target=consommateur,args=(f, ))
t1.start()
t2.start()



### Barbier


from threading import *
import time
import random
c=Condition()
b=0
s=0

a=[]

def Barbier():
    global b,c,s,a
    while True:
        #if (s==0):
        c.acquire()
        while(s==0):
            b=0
            print("[Barbier ] Je fais la sieste")
            c.wait()
        s=s-1
        i=a.pop(0)
        print("[Barbier ] Je coiffe le client "+str(i))
        time.sleep(2)
        print("[Barbier ] J'ai fini le client "+str(i))
        c.notify_all()
        c.release()

def client(i):
    global b,c,s,a
    while True:
        c.acquire()
        #if (s>4):
        while(s>4):
            print("[Client "+str(i)+"] Le salon est plein, je reviendrai plus tard")
            c.wait()
        
        while True:
            c.acquire()
            print("[Client "+str(i)+"] Je rentre dans le salon")
            s=s+1
            if(b==0):
                print("[Client "+str(i)+"] Je reveille le barbier")
                b=1
            a.append(i)
            
            print("[Client "+str(i)+"] Je suis en train d'etre coiffe par le barbier")
            time.sleep(5)
            c.notify_all()
            c.release()
            print("[Client "+str(i)+"] J'ai fini d'etre coiffe")
            print("[Client "+str(i)+"] Je sors du salon")
            a.pop(0)
                    
    time.sleep(int(random.expovariate(0.1)))

barb=Thread(target=Barbier)
clt=[]
for i in range(5):
    clt.append(Thread(target=client, args=(i,)))

barb.start()
for i in range(5):
    clt[i].start()
    
## Serveur de multithreadé

Telnet : outil de connexion à distance sur un port dédié
https://home.mis.u-picardie.fr/~utard/dokuwiki/doku.php?id=serverthread&s[]=mini&s[]=projet