2015-06-18 2 views
2

У меня есть код клиентского сервера на python, где клиент запрашивает сервер о процессе, запущенном на сервере, и предоставляет порог памяти. Если процесс потребляет больше памяти, чем порог, сервер убивает процесс и перезапускает его. Проблема в том, что я создаю новый поток для каждого клиента, поток после обслуживания клиента должен завершаться, освобождая соединения и перезагружая убитый процесс. Когда я запускаю только один поток (i.e ТОЛЬКО ОДИН КЛИЕНТ), все работает нормально. Но когда я запускаю несколько клиентов, только один из них освобождает соединение и перезапускает процесс, в то время как другие потоки только перезапускают процесс, но не подключаются. Я звоню в модуль Popen.subprocess() внутри потоков. Это причина или есть еще одна причина для этого?Popen.subprocess в потоках

Вот мой код:

from thread import * 
import threading 
import time 
import psutil 
import itertools 
import ctypes 
import string 
import os 
import sys 
import socket 
import subprocess 
from datetime import datetime 

def drives(): 
    drive_bitmask = ctypes.cdll.kernel32.GetLogicalDrives() 
    return list(itertools.compress(string.ascii_uppercase,map(lambda x:ord(x) - ord('0'), bin(drive_bitmask)[:1:-1]))) 

t=0 
c=drives() 
o=[] 
while(t<len(c)): 
    o.append(str(c[t]+':\\')) 
    t=t+1 


class procThread(threading.Thread): 
    def __init__(self,conn,addr): 
     threading.Thread.__init__(self) 
     self.conn=conn 
     self.addr=addr 


    def run(self): # prints the process's info which match the keyword....... SERVER SIDE 
    self.conn.send('Welcome to the server\n') 
    name=[] 
    global o 
    m=0 
    k=0 
    self.conn.send("Enter the key...\n") # for authentication purposes...e.g.here the key is 1 
    t=self.conn.recv(8) 
    if(t!='1'): #WRONG KEY....INVALID USER 
     self.conn.send("\nInvalid key..teminating the connection.....ABORT\n") 
     self.conn.close() 
     else: 
       fp=open("processlogs.txt","a") 
     r="" 
     self.conn.send("\nEnter the process keyword ..Press # @ the end ") # e.g. 'Sk' for Skype 
     d=self.conn.recv(65536) 
     while(d!='#'): 
        r=r+str(d) 
      d=self.conn.recv(65536) 
     for p in psutil.pids(): # iterates through all the pids of the processes obtained 
        try: 
         p1=psutil.Process(p) 
      if(r in p1.name()): 
          p2=p1.get_memory_info() 
          t=p1.name()+' ' 
          d=str(p)+' ' 
          self.conn.send(d)# prints the pid of the process 
          self.conn.send(t),# prints the name of the process 
          d=str(p2[0]/(1024*1024))+' ' 
          self.conn.send(d) # print memory in MB 
          self.conn.send('MB\t') 
          for connect in p1.connections(kind='tcp'): 
           d=str(connect.laddr[0])+' ' 
       self.conn.send(d) # prints ip 
           d=str(connect.laddr[1])+' ' 
       self.conn.send(d) # prints tcp ports       
        except psutil.AccessDenied: # won't show all the processes 
         pass 
        except psutil.NoSuchProcess: 
         pass 
      else: 
         continue 
     self.conn.send(" Enter the threshold...(in MB)(Press # at the end) ") 
     d="" 
     t=self.conn.recv(65536).decode('utf-8') 
     while(t!='#'): 
        d=d+str(t) 
        t=self.conn.recv(65536).decode('utf-8') 
       names=[]  # LIST OF PROCESSES TO BE KILLED...#A RECORD IS KEPT SO THAT THEY CAN BE RESTARTED...... 
       for p in psutil.pids(): 
        try: 
         p1=psutil.Process(p) 
         if(r in p1.name()): 
          if((p2[0]/(1024*1024))>=int(d)): 
           fp.write(str(datetime.now().strftime('%Y-%m-%d %H:%M:%S'))) 
           fp.write("|") 
           fp.write(str(self.addr)) 
           m=p1.name() 
           m=m.encode('ascii','ignore') # converting unicode object into string object 
           for l in o: 
            f=0 
            for root, dirs, files in os.walk(l): # walks through the entire file system of the Windows OS 
             for name in files: 
              if name==m: 
               p1.kill() 
               self.conn.send("  Finally the process is killed...... ") 
               f=1 
               self.conn.send(str(os.path.abspath(os.path.join(root,name)))) 
               fp.write("|") 
               fp.write(str(os.path.abspath(os.path.join(root,name)))+'\n') 
               names.append(os.path.abspath(os.path.join(root,name))) 
               break 
             if(f==1): 
              break 

            if(f==1): 
             break 

        except psutil.AccessDenied: 
         pass 
        except psutil.NoSuchProcess: 
         pass 
        else: 
         continue 
       self.conn.send(" Now the processes will be restarted after the connection is terminated......") 
       fp.close() 
       self.conn.close() # closes the connection... 
       if(names): 
        for l in names: 
         subprocess.Popen(str(l)) 

class serverThread(threading.Thread): # Thread class for Server(FOR LISTENING) 
    def __init__(self, threadID, name,): 
     threading.Thread.__init__(self) 
     self.threadID = threadID 
     self.name = name 
    def run(self): 
     threadLock.acquire() 
     host=raw_input("Enter the hostname.....") 
     HOST=socket.gethostbyname(host) 
     PORT=input("Enter the port no......") # specific port available 
     s=socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
     print 'Socket created' 
     #Bind socket to local host and port 
     try: 
      s.bind((HOST, PORT)) 
     except socket.error as msg: 
      print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1] 
      sys.exit() 
     print 'Socket bind complete' 
     s.listen(10) # no of connections @ one time 
     print self.name+' now listening' 
     threadLock.release() 
     while 1: 
      conn, addr = s.accept() # connection gets established here.. 
      print 'Connected with ' + addr[0] + ':' + str(addr[1]) 
      conn.send('Thank you for connecting ') 
      procs=procThread(conn,addr) 
      procs.start() 
      #start_new_thread(proc_info,(conn,addr)) 
     s.close() 
print("WELCOME") 
print(" server-client") 
threadLock=threading.Lock() 
thread1 =serverThread(1,"Server 1") 
thread1.start() # starting the server thread... 
+0

Клиент подключается к серверу через cmd – rahuljain1313

ответ

0

Проблема может быть, что некоторые исключения становятся выброшены, прежде чем процесс может закрыть соединение. Вы должны попробовать следующее предложение и проверить, так ли это.

Вы должны сделать это привычкой, чтобы написать код, чтобы закрыть соединение в конце концов блокировать, что-то вроде -

try: 
    <code you want to execute , may even include the creation of connection, etc> 
finally: 
    conn.close() 

Это убедиться, что даже если есть некоторые ошибки/исключения выброшен из кода перед Вызывается conn.close(), он все равно выполняется. Кроме того, хорошая практика сохранить эти виды санитарного кода (код очистки) в конце функции/скрипта, чтобы они выполнялись в конце, хотя это может не всегда применяться в соответствии с требованием.

Смежные вопросы