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:

# -*- 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:

# -*- 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:

# -*- 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()