La programmation asynchrone avec python

La programmation asynchrone permet de lancer plusieurs processus simultanément. Cela permet dans certains cas un gain important de temps.

Un exemple est souvent plus parlant. Voici un script qui scan votre réseau local:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import subprocess
import re

# on prépare la regex
regex = re.compile(r"(?P<received>\d+) received")

# la fonction qui assure le ping
def ping(hostname):
    p = subprocess.Popen(["ping", "-c1", "-w100", hostname], stdout=subprocess.PIPE).stdout.read()
    r = regex.search(p.decode())
    try:
        if(r.group("received") == "1"):
            print("L'adresse %s existe!" % hostname) 
    except:
        pass

# on boucle sur les adresses du réseau local
for i in range(254):
    hostname = "192.168.0.%i" % (i+1)
    ping(hostname)

Comme vous pouvez le constater le programme met un certain temps à s'exécuter puisque si un ping ne repond pas, on doit attendre le temps obligatoire avant de passer au test suivant. Pour gagner du temps on peut donc passer à la programmation asynchrone, c'est à dire de lancer toutes les instructions en même temps:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import subprocess
import re
import threading

# on prépare la regex
regex = re.compile(r"(?P<received>\d+) received")

# la fonction qui assure le ping
def ping(hostname):
    p = subprocess.Popen(["ping", "-c1", "-w100", hostname], stdout=subprocess.PIPE).stdout.read()
    r = regex.search(p.decode())
    try:
        if(r.group("received") == "1"):
            print("L'adresse %s existe!" % hostname) 
    except:
        pass

# on boucle sur les adresses du réseau local
for i in range(254):
    hostname = "192.168.0.%i" % (i+1)
    threading.Thread(target=ping,args=(hostname,)).start()

Vous pouvez passer par une classe également:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import subprocess
import re
import threading

regex = re.compile(r"(?P<received>\d+) received")

class Ping(threading.Thread):

    def __init__(self, hostname):
        threading.Thread.__init__(self)
        self.hostname = hostname

    def run(self):
        p = subprocess.Popen(["ping", "-c1", "-w100", self.hostname], stdout=subprocess.PIPE).stdout.read()
        r = regex.search(p.decode())
        try:
            if(r.group("received") == "1"):
                print("L'adresse %s existe!" % self.hostname) 
        except:
            pass

for i in range(254):
    hostname = "192.168.0.%i" % (i+1)
    background = Ping(hostname)
    background.start()