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

Prochaine révision
Révision précédente
python_multiprocessing [2021/08/12 13:30] – créée 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. +
- +
-=====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.
  
-=====Exemples=====+=====Exemples de Multiprocessing=====
 Je vous propose des exemples simples: Je vous propose des exemples simples:
 +
 +<file python multiprocessing_example_1.py>
 +"""
 +Exemple d'utilisation de multiprocessing
 +
 +documentation
 +https://docs.python.org/3/library/multiprocessing.html
 +
 +Exemple de 2 processus qui tournent en parallèle sans communiquer.
 +"""
 +
 +
 +import os
 +from multiprocessing import Process
 +from time import sleep
 +
 +def first_processus():
 +    print('first process:', os.getppid())
 +    a = 0
 +    while 1:
 +        sleep(1)
 +        a += 1
 +        print("a =", a)
 +
 +def second_processus():
 +    print('second process:', os.getppid())
 +    b = 0
 +    while 1:
 +        sleep(2)
 +        b += 5
 +        print("b =", 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.1628775019.txt.gz · Dernière modification : 2021/08/12 13:30 de serge