• [^] # Pour compléter ces exemples, la version avec socket non-bloquantes

    Posté par . En réponse au message Communication inter-processus. Évalué à 3.

    Bon alors pour mon exemple ça ne sert à rien d’avoir des sockets non-bloquantes puisse qu’il y en a qu’une mais dans le cas où on devrait en manipuler plusieurs on peut faire ainsi :

    #!/usr/bin/env python3
    import sys
    import subprocess
    import socket
    import signal
    import select
    import os
    pidFilename = '/tmp/'+sys.argv[0]+'.pid'
    def graceful_exit(signum, frame):
     print('I terminate, my PID is '+str(os.getpid())+' and I received signal '+str(signum)+'', file=sys.stderr, flush=True)
     sys.exit(0)
    try:
     if sys.argv[1] == 'start':
     sleeper = subprocess.Popen([sys.argv[0], 'run'], stdin=subprocess.PIPE, shell=False)
     pidfile = open(pidFilename,'w')
     _pid = str(sleeper.pid)
     pidfile.write(_pid)
     pidfile.close()
     elif sys.argv[1] == 'run':
     signal.signal(signal.SIGTERM, graceful_exit)
     signal.signal(signal.SIGINT, graceful_exit)
     server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     server.bind(('127.0.0.1', 1234))
     server.setblocking(0)
     server.listen(3)
     while True:
     _sockets_ready = select.select([server],[],[])
     client, addr = _sockets_ready[0][0].accept()
     message = client.recv(65535).decode('UTF-8')
     if message:
     print('I’m alive, my PID is '+str(os.getpid())+' and I’ve been told to say : « '+message+' »', file=sys.stderr, flush=True)
     elif sys.argv[1] == 'stop': 
     try:
     pidfile = open(pidFilename,'r')
     os.kill(int(pidfile.read()), signal.SIGTERM)
     pidfile.close()
     os.unlink(pidFilename)
     except (FileNotFoundError, ProcessLookupError):
     pass
     elif sys.argv[1] == 'say' and len(sys.argv) > 1:
     try:
     client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     client.connect(('127.0.0.1', 1234))
     client.send(bytes(sys.argv[2],'utf8'))
     except ConnectionRefusedError as e:
     print(str(e), file=sys.stderr)
    except IndexError as e:
     print(str(e), file=sys.stderr)

    C’est le select qui prend en objet les trois listes de sockets (potential_readers, potential_writers, potential_errs) et retourne ces trois listes avec seulement les sockets qui sont prêtes :

    _sockets_ready = select.select([server],[],[])
    client, addr = _sockets_ready[0][0].accept()
    message = client.recv(65535).decode('UTF-8')

    Ici le accept() n’aura pas lieu tant qu’il n’y a rien à lire sur la socket 'server', « bloquant » ainsi la boucle while, qui n’a effectivement aucune raison de tourner s’il n’y a rien à lire...

    https://docs.python.org/3/howto/sockets.html#non-blocking-sockets

    J’espère ne pas avoir raconté trop de connerie et qu’on me corrigera le cas échéant.