簡體   English   中英

線程中的Popen.subprocess

[英]Popen.subprocess in threads

我在python中有一個客戶端服務器代碼,其中客戶端向服務器查詢服務器上正在運行的進程並提供內存閾值。 如果該進程消耗的內存超過閾值,則服務器將終止該進程並重新啟動它。 問題是,由於我正在為每個客戶端創建一個新線程,因此在為客戶端提供服務后,該線程應自行終止,釋放連接並重新啟動終止的進程。 當我只運行一個線程( 即ONLY ONE CLIENT )時,一切正常。 但是,當我運行多個客戶端時, 只有其中一個會釋放連接並重新啟動進程,而其他線程只會重新啟動進程而不連接。 我在線程內調用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...

問題可能是在進程可以關閉連接之前引發了一些異常。 您應該嘗試以下建議,並檢查是否是這種情況。

您應該養成一種習慣,編寫代碼以在finally塊中關閉連接,例如-

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

這樣可以確保即使在調用conn.close()之前從代碼中拋出了一些錯誤/異常,它仍然會執行。 另外,一種好的做法是將這些類型的衛生代碼(清除代碼)保留在函數/腳本的末尾,以便它們在末尾執行,盡管根據要求可能並不總是適用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM