【发布时间】:2022-01-10 10:24:31
【问题描述】:
说明
我正在用 python3 中的套接字做一个架构服务器-多客户端。
为此,我使用多处理库。 下面的代码,创建一个服务器监听客户端连接:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(("",PORT))
sock.listen(CLIENTS)
print(logFile().message(f"running ClassAdmin server, listen {CLIENTS} clients by port {PORT}...",True,"INFO"))
sockSSL = context.wrap_socket(sock,server_side=True)
while sockSSL:
connection, address = sockSSL.accept()
eventChildStop = multiprocessing.Event()
subprocess = multiprocessing.Process(target=ClientListener, name="client", args=(connection, address))
subprocess.start()
在上面的代码中,每个客户端都在一个子进程中执行。与multiprocessing.Process()
这会运行类ClientListener。
class ClientListener:
def __init__(self,conn,addr):
try:
self.conn, self.addr = conn, addr
self.nick = ""
self.__listenData()
except (KeyboardInterrupt,SystemExit) as err:
print(logFile().message(f"The host {self.nick} ({self.addr[0]}:{self.addr[1]}) left", True, "INFO"))
except BaseException as err:
type, object, traceback = sys.exc_info()
file = traceback.tb_frame.f_code.co_filename
line = traceback.tb_lineno
print(logFile().message(f"{err} in {file}:{line}", True, "ERROR"))
finally:
try:
ListClients().remove(self.conn)
self.conn.close()
except:
None
finally:
Client(self.conn,self.addr).registre(self.nick,"DISCONNECTED",False)
def __listenData(self):
while True:
data = self.conn.recv(1024)
text = data.decode('utf-8')
if text.startswith("sig."):
exec(f"raise {text.split('.')[1]}")
elif data:
if text.startswith("HelloServer: "):
self.nick = text.replace("HelloServer: ","")
client = Client(self.conn,self.addr).registre(self.nick, "CONNECTED", False)
if client==False:
self.conn.send(b"sig.SystemExit(-5000,'The nick exists and is connected',True)")
else:
print(logFile().message(f"The host {self.nick} ({self.addr[0]}:{self.addr[1]}) is connected", True, "INFO"))
ListClients().add(self.conn)
else:
print(data)
在__init__()中运行__listenData()方法,该方法负责处理客户端在服务器端发送的数据。
在__init__() 中,我处理异常以在关闭客户端时显示信息。
try:
#{...}
finally:
try:
ListClients().remove(self.conn)
self.conn.close()
except:
None
finally:
Client(self.conn,self.addr).registre(self.nick,"DISCONNECTED",False)
#HERE, Can I close the current child process?
在这个try执行finally,因为总是会删除客户端列表中的客户端,如果有连接会关闭它。
问题
我的问题如下:
-
当我在服务器上连接客户端时,在服务器进程中创建了一个子进程。
我的问题是……
如何关闭这个子进程?由于客户端在由multiprocessing.Process() 启动的子进程中运行。我必须使用multiprocessing 的方法terminate() 关闭它...我认为这就是解决方案。
可以解决吗?
我想...
- 在根目录中添加侦听
multiprocessing.Event()的其他子进程:
while sockSSL:
connection, address = sockSSL.accept()
eventChildStop = multiprocessing.Event()
subprocess = multiprocessing.Process(target=ClientListener, name="client", args=(connection, address,eventChildStop))
subprocess.start()
multiprocessing.Process(target=ClientListener.exitSubprocess, name="exitChildProcess",args=(eventChildStop, subprocess)).start()
time.sleep(1)
- 在
listenerClients类中,我在__init__()中添加参数event:
class ClientListener:
def __init__(self,conn,addr,event):
- 我添加了静态方法
exitSubprocess()。这个方法在理论上终止子进程(不是这样):
@staticmethod
def exitSubprocess(event,process):
while True:
if event.is_set():
print(process.id)
process.terminate()
break
time.sleep(.5)
但是,事实并非如此,结果是一样的。子进程(一个是方法静态exitSubprocess。第一个是客户端进程)是状态Zombie。为什么...?
有人明白发生了什么吗?
我感谢有人回复。感谢您的关注。
【问题讨论】:
标签: python-3.x sockets multiprocessing