Popen.subprocess 在线程中
Popen.subprocess in threads
我在 python 中有一个客户端服务器代码,其中客户端向服务器查询服务器上的进程 运行 并提供内存阈值。如果进程消耗的内存超过阈值,服务器会终止进程并重新启动它。问题是因为我正在为每个客户端创建一个新线程,服务客户端后的线程应该自行终止,释放连接并重新启动被杀死的进程。当我 运行 只有一个线程时( 即只有一个客户端 ),一切正常。但是当我是运行多个客户端时,只有其中一个释放连接并重新启动进程,而其他线程只重新启动进程但不连接。我调用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() 之前从代码中抛出一些 errors/exceptions,它仍然会被执行。此外,将这些类型的卫生代码(清理代码)保留在 function/script 的末尾是一个很好的做法,以便它们在 end 执行,尽管根据要求这可能并不总是适用。
我在 python 中有一个客户端服务器代码,其中客户端向服务器查询服务器上的进程 运行 并提供内存阈值。如果进程消耗的内存超过阈值,服务器会终止进程并重新启动它。问题是因为我正在为每个客户端创建一个新线程,服务客户端后的线程应该自行终止,释放连接并重新启动被杀死的进程。当我 运行 只有一个线程时( 即只有一个客户端 ),一切正常。但是当我是运行多个客户端时,只有其中一个释放连接并重新启动进程,而其他线程只重新启动进程但不连接。我调用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() 之前从代码中抛出一些 errors/exceptions,它仍然会被执行。此外,将这些类型的卫生代码(清理代码)保留在 function/script 的末尾是一个很好的做法,以便它们在 end 执行,尽管根据要求这可能并不总是适用。