Outils pour utilisateurs

Outils du site


python_multiprocessing

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentesRévision précédente
Prochaine révision
Révision précédente
python_multiprocessing [2021/08/12 13:40] – [Remarques] sergepython_multiprocessing [2022/06/21 13:42] (Version actuelle) – [Mon exemple à moi archi simple] serge
Ligne 1: Ligne 1:
 ====== Python: Multiprocessing et GIL ====== ====== Python: Multiprocessing et GIL ======
 +=====Python est lent et n'est pas multiprocessus=====
 +Balivernes ... billevesées ... \\
 +Toutes les Intelligences Artificielles ont une façade en python ... Dja dja (ah bon!)\\
 +L'interpréteur python est généralement CPython qui est comme son nom l'indique écrit en C, le C serait lent ?
  
  
-=====Python est lent et n'est pas multiprocess=====+=====GIL===== 
 +  * **https://realpython.com/python-gil/** 
 +Le module threading permet de lancer des tâches en parallèles, mais en réalité elles ne le sont pas: tout se fait sur un seul cœur du processeur. Les tâches sont découpées en petits bouts, exécution d'un bout d'une, puis un petit de l'autre, etc ...
  
-Ballivernes ... billevesées ... \\ +Le GIL (Global Interpreteur Lockévite de surcharger un thread.
-Toutes les Intelligences Artificielles ont une façade en python ... Dja daja (ah bon!)\\ +
-L'interpréteur python est généralement CPython qui est comme son nom l'indique écrit en C, le C serait lent ? +
- +
-=====Ressources sur le module multiprocessing=====+
  
 +Le module multiprocessing utilise réellement un cœur pour chaque tâche, et il est possible que chaque tâche communique avec une autre.\\
 +Par contre, un processus n'utilise toujours qu'un seul cœur.
  
 +=====Ressources sur le module multiprocessing=====
   * http://www.kasimte.com/multiprocessing-in-python-pool-process-queue-and-pipe   * http://www.kasimte.com/multiprocessing-in-python-pool-process-queue-and-pipe
   * https://stackoverflow.com/questions/11515944/how-to-use-multiprocessing-queue-in-python   * https://stackoverflow.com/questions/11515944/how-to-use-multiprocessing-queue-in-python
Ligne 16: Ligne 21:
   * https://www.geeksforgeeks.org/multiprocessing-python-set-2/   * https://www.geeksforgeeks.org/multiprocessing-python-set-2/
  
-Mais comme souvent, les tutos sont hyper-compliqués, les auteurs montrent qu'ils sont très fort avec des exemples inappropriés. +Mais comme souvent, les tutos sont hyper-compliqués, les auteurs montrent qu'ils sont très forts avec des exemples inappropriés. 
  
 ===Remarques=== ===Remarques===
 Certains modules, tel que numpy, sont déjà multiprocess. Certains modules, tel que numpy, sont déjà multiprocess.
  
-=====GIL===== +=====Exemples de Multiprocessing===== 
-Le module threading permet de lancer des tâches en parallèles, mais en réalité elles ne le sont pastous se fait sur un seul cœurs du processeur. Les tâches sont découpées en petits bouts, excécution d'un bout d'une, puis un petit de l'autre, etc ...+Je vous propose des exemples simples:
  
-Le GIL (Global Interpreteur Lock) évite de surcharger un thread.+<file python multiprocessing_example_1.py> 
 +""" 
 +Exemple d'utilisation de multiprocessing
  
-Le module multiprocessing utilise réellement un cœur pour chaque tâche, et il est possible que chaque tâche communique avec une autre.\\ +documentation 
-Par contre, un processus n'utilise toujours qu'un seul cœur.+https://docs.python.org/3/library/multiprocessing.html
  
-=====Exemples===== +Exemple de 2 processus qui tournent en parallèle sans communiquer. 
-Je vous propose des exemples simples+""" 
-{{tag>python sb}}+ 
 + 
 +import os 
 +from multiprocessing import Process 
 +from time import sleep 
 + 
 +def first_processus(): 
 +    print('first process:', os.getppid()) 
 +    a 
 +    while 1: 
 +        sleep(1) 
 +        a +
 +        print("=", a) 
 + 
 +def second_processus(): 
 +    print('second process:', os.getppid()) 
 +    b 
 +    while 1: 
 +        sleep(2) 
 +        b +
 +        print("=", b) 
 + 
 +def main(): 
 +    p Process(target=second_processus) 
 +    p.start() 
 +    first_processus() 
 + 
 +if __name__ == '__main__': 
 +    main() 
 +</file> 
 + 
 +<file python multiprocessing_example_2.py> 
 +""" 
 + 
 +Exemple de 2 processus qui tournent en parallèle et échangent une variable avec Pipe. 
 +https://docs.python.org/3/library/multiprocessing.html#exchanging-objects-between-processes 
 + 
 +The Pipe() function returns a pair of connection objects connected 
 +by a pipe which by default is duplex (two-way). 
 +""" 
 + 
 + 
 +import os 
 +from multiprocessing import Process, Pipe 
 + 
 + 
 +def test(n): 
 +    """Fonction pour charger le processeur""" 
 +    for i in range(n): 
 +        m = (i ** 1.89999) ** 0.8974125 
 + 
 + 
 +def first_processus(conn): 
 +    print('first process:', os.getppid()) 
 +    a = 0 
 +    while 1: 
 +        test(1000000) 
 +        a += 1 
 +        print("a =", a) 
 +        b = conn.recv() 
 +        print("b dans first_process =", b) 
 +        a += b[1] 
 + 
 +def second_processus(conn): 
 +    print('second process:', os.getppid()) 
 +    b = 0 
 +    while 1: 
 +        test(2000000) 
 +        b += 5 
 +        print("b dans second process =", b) 
 +        conn.send(['b', b]) 
 + 
 + 
 +def main(): 
 +    """ 
 +    https://docs.python.org/3/library/multiprocessing.html#multiprocessing.Pipe 
 +    multiprocessing.Pipe([duplex]) 
 +    If duplex is True (the default) then the pipe is bidirectional. If duplex is 
 +    False then the pipe is unidirectional: conn1 can only be used for receiving 
 +    messages and conn2 can only be used for sending messages. 
 +    """ 
 +    parent_conn, child_conn = Pipe() 
 +    p = Process(target=second_processus, args=(child_conn,)) 
 +    p.start() 
 +    first_processus(parent_conn) 
 + 
 + 
 +if __name__ == '__main__': 
 +    main() 
 +</file> 
 + 
 +=====Multiprocess dans kivy===== 
 +Une application kivy qui excécute pyrealsense et coral dans un Process avec Pipe marche impeccable. 
 + 
 +  * **[[https://github.com/sergeLabo/personnages3d| sergeLabo personnages3d]]** Détection de 1 à 4 personnes 
 +    * Inferface graphique réalisée avec Kivy\\ 
 +    * Suivi des personnes devant la caméra 
 + 
 +=====multiprocessing.shared_memory ===== 
 +====Ressources==== 
 +  * **[[https://docs.python.org/fr/3.9/library/multiprocessing.shared_memory.html|docs.python.org/fr Mémoire partagée en accès direct depuis plusieurs processus¶]]**  
 + 
 +====Mon exemple à moi archi simple==== 
 +**Je n'ai pas besoin de montrer que je suis très fort pour me faire embaucher chez GAFAM.** 
 + 
 +<code python> 
 +from time import time, sleep 
 +import random 
 +from multiprocessing import Process 
 +from multiprocessing.sharedctypes import Value 
 + 
 +class SharedMemory: 
 +    def __init__(self): 
 +        self.val = Value("i", -4000) 
 +        print(self.val, self.val.value) 
 +        my_proc = Process(target=another_process,  args=(self.val, )) 
 +        my_proc.start() 
 + 
 +    def shared_memory_master(self): 
 +        t = time() 
 +        while time() - t < 4: 
 +            print(f"Lecture de {self.val}: {self.val.value}"
 +            sleep(0.1) 
 + 
 +def another_process(val): 
 +    t = time() 
 +    while time() - t < 3: 
 +        n = random.randint(-1000, 1000) 
 +        print(f"Maj de n = {n}"
 +        val.value = n 
 +        sleep(0.3) 
 + 
 +if __name__ == "__main__": 
 +    sh = SharedMemory() 
 +    sh.shared_memory_master() 
 +</code> 
 +====Exemple d'utilisation bas niveau d'instances de SharedMemory==== 
 + 
 +<code python> 
 +from multiprocessing import shared_memory 
 + 
 +shm_a = shared_memory.SharedMemory(create=True, size=10) 
 +m = shm_a.buf 
 +print('type(m)', type(m)) 
 + 
 +buffer = shm_a.buf 
 +print('len(buffer)', len(buffer)) 
 + 
 +# Modify multiple at once 
 +buffer[:4] = bytearray([22, 33, 44, 55]) 
 +# Modify single byte at a time 
 +buffer[4] = 100 
 + 
 +# Attach to an existing shared memory block 
 +shm_b = shared_memory.SharedMemory(shm_a.name) 
 + 
 +import array 
 + 
 +# Copy the data into a new array.array 
 +ar = array.array('b', shm_b.buf[:5]) 
 +print('ar', ar) 
 + 
 +# Modify via shm_b using bytes 
 +shm_b.buf[:5] = b'howdy' 
 + 
 +# Access via shm_a 
 +print('bytes(shm_a.buf[:5])', bytes(shm_a.buf[:5])) 
 + 
 +# Close each SharedMemory instance 
 +shm_b.close() 
 +shm_a.close() 
 + 
 +# Call unlink only once to release the shared memory 
 +shm_a.unlink() 
 +</code> 
 + 
 +====Exemple de partage de numpy array==== 
 +<code python> 
 +from multiprocessing import Process 
 +from multiprocessing.managers import SharedMemoryManager 
 +from multiprocessing.shared_memory import SharedMemory 
 + 
 +import numpy as np 
 + 
 + 
 +def test(shared_mem: SharedMemory, dtype): 
 +    a = np.frombuffer(shared_mem.buf, dtype=dtype) 
 +    a[0] = -a[0] 
 + 
 + 
 +if __name__ == "__main__": 
 +    # Create the array 
 +    N = int(10) 
 +    unshared_arr = np.random.rand(N) 
 +    DTYPE = unshared_arr.dtype 
 +    with SharedMemoryManager() as smm: 
 +        shared_mem = smm.SharedMemory(size=unshared_arr.nbytes) 
 +        arr = np.frombuffer(shared_mem.buf, dtype=DTYPE) 
 +        arr[:] = unshared_arr 
 +        print("Originally, the first two elements of arr = %s" % (arr[:2])) 
 + 
 +        # Create, start, and finish the child processes 
 +        p = Process(target=test, args=(shared_mem, DTYPE)) 
 +        p.start() 
 +        p.join() 
 + 
 +        # Printing out the changed values 
 +        print("Now, the first two elements of arr = %s" % arr[:2]) 
 +</code> 
 + 
 + 
 +{{tag> kivy python sb }}
python_multiprocessing.1628775620.txt.gz · Dernière modification : 2021/08/12 13:40 de serge