2017-09-28 9 views
0

J'essaie d'exécuter un script python (Activator) qui va exécuter un autre script (client) et le terminer après un certain laps de temps. (5 secondes dans cet exemple).temps réel en sous-processus python ne fonctionne pas sur la console de Windows

Activator

import random, sys, os, socket 
 
import time, datetime 
 
import subprocess 
 
from threading import Thread 
 
from multiprocessing import Queue 
 

 

 
class deamon_pckg: 
 
    def __init__(self, msg_type, info, exeption=None): 
 
     self.msg_type = msg_type 
 
     self.info = info 
 
     self.exception = exeption 
 

 

 
class Process_comm: 
 
    @staticmethod 
 
    def deamon(process, q): 
 
     while process.poll() is None: 
 
      out = process.stdout.readline().rstrip() 
 
      if out != '': 
 
       d_pckg = deamon_pckg('cmd', out) 
 
       q.put(d_pckg) 
 

 
     exit_code = process.returncode 
 
     if exit_code != 0: 
 
      err_msg = process.stderr.read() 
 
     else: 
 
      err_msg = None 
 
     d_pckg = deamon_pckg('EXIT', exit_code, err_msg) 
 
     q.put(d_pckg) 
 

 
    def __init__(self, process): 
 
     self.process = process 
 
     self.q = Queue() 
 
     self.d = Thread(target=Process_comm.deamon, args=(self.process, self.q)) 
 
     self.d.start() 
 

 
    def close(self): 
 
     if self.process.returncode is None: 
 
      self.terminate() 
 
     self.d.join() 
 

 
    def terminate(self): 
 
     self.process.terminate() 
 

 
    def get(self, blocking=False): 
 
     if blocking: 
 
      return self.q.get() 
 
     else: 
 
      if self.q.empty(): 
 
       return None 
 
      else: 
 
       return self.q.get() 
 

 

 
if __name__ == '__main__': 
 
    print "Activator online" 
 
    start_time = datetime.datetime.now() 
 
    process = subprocess.Popen(['python', "C:\work\Router\src\demiborg.py"], 
 
           stdout=subprocess.PIPE, 
 
           stderr=subprocess.PIPE) 
 
    d = Process_comm(process) 
 

 

 
    while True: 
 
     delta = (datetime.datetime.now() - start_time) 
 
     dpckg = d.get() 
 
     if delta.seconds >= 5: 
 
      d.terminate() 
 
      break 
 
     if dpckg is None: 
 
      time.sleep(0.1) 
 
     else: 
 
      if dpckg.msg_type == 'EXIT': 
 
       print "[{}]\t{}".format(dpckg.msg_type, dpckg.info) 
 
       if dpckg.exception is not None: 
 
        print "{}".format(dpckg.exception) 
 
       break 
 
      else: 
 
       print "[{}]\t{}".format(dpckg.msg_type, dpckg.info) 
 
    d.close()

Client:

import random, sys, os, socket 
 
import time, datetime 
 

 

 
def get_time_stamp(): 
 
    ts = time.time() 
 
    st = datetime.datetime.fromtimestamp(ts).strftime('%f:%S:%M:%H:%d:%m:%Y') 
 
    return st 
 

 
def put(fout,msg): 
 
    fout.write('[{:>30}]'.format(get_time_stamp()) + '\t' + msg + '\n') 
 
    fout.flush 
 
    print msg 
 

 

 
if __name__ == '__main__': 
 
    fout = open('demiborg.txt','wb') 
 
    put(fout,"Start DemiBorg") 
 
    for i in range(20): 
 
     put(fout,"time - {}".format(i)) 
 
     time.sleep(0.5) 
 

 
    put(fout,'End') 
 
    fout = open('ERROR', 'wb') 
 
    fout.close()

Si je cours

Activator online 
 
[cmd] \t Start DemiBorg 
 
[cmd] \t time - 0 
 
[cmd] \t time - 1 
 
[cmd] \t time - 2 
 
[cmd] \t time - 3 
 
[cmd] \t time - 4 
 
[cmd] \t time - 5 
 
[cmd] \t time - 6 
 
[cmd] \t time - 7 
 
[cmd] \t time - 8 
 
[cmd] \t time - 9 
 

 
Process finished with exit code 0

Mais quand je le lance via la console windows je reçois pas d'entrée du tout (comme le client n'a pas couru).

C:\work\Router\src>C:\work\Router\src\plygrnd_activator.py 
 
Activator online 
 

 
C:\work\Router\src>

encore plus, si un n'a pas tué le client, je remarquai que tous les messages sont venus comme un seul bloc ensemble seulement après que le client a terminé la course. pourquoi seulement en utilisant pycharm cela fonctionne bien mais sur la console je ne reçois pas de commentaires en direct? le but est de courir sur la console. Merci!

Répondre

0

Solution, le problème était dans la taille du tampon.

au lieu d'utiliser:

process = subprocess.Popen(['python', "C:\work\Router\src\demiborg.py"], 
 
           stdout=subprocess.PIPE, 
 
           stderr=subprocess.PIPE)

j'ai ajouté le drapeau "-u" après le "python":

process = subprocess.Popen(['python','-u', "C:\work\Router\src\demiborg.py"], 
 
           stdout=subprocess.PIPE, 
 
           stderr=subprocess.PIPE)