[英]Python terminate multiprocessing and gui process gracefully
我使用林间空地作为我的GUI,并创建了一个运行我的GUI的进程。单击“打开”时,此应用程序将打开一个套接字。 当我按“发送”时,它将文本字段中的所有内容发送到套接字。 套接字接收此数据并将其发送回。 问题是我将数据发送到套接字后,线程没有终止。 另外,在我关闭GUI后,它会调用sys.exit(),但也会留下一个进程,并且不会终止。 我认为错误在于我如何实现流程或总体上所有流程。 谁能对此有所启发? 它也与我的上一篇文章有关。 谢谢
main.py
//主线程为我的GUI创建一个新进程并显示它
import socket, thread, gtk, Handler, sys, os, multiprocessing
sys.setrecursionlimit(10000)
if __name__ == '__main__':
builder = gtk.Builder()
#32bit template.glade 64bit template-2.22
# @todo add switching between architectures
#
builder.add_from_file("template/template-2.22.glade")
builder.connect_signals(Handler.Handler(builder))
window = builder.get_object("window1")
window.show_all()
try:
p = multiprocessing.Process(target=gtk.main())
p.start()
except:
print "Error Starting new Thread"
handler.py
// gtk Glade信号的处理程序,创建新线程并处理按钮和内容
import thread, threading, os, server, client,multiprocessing, time
import sys, gtk
class Handler(object):
'''
classdocs
'''
myobject = ''
def __init__(self,object1):
#Getting glade builder
self.myobject = object1
'''
Constructor
'''
def clickme(self,value):
myserver = server.Server()
try:
p = multiprocessing.Process(target=myserver.run)
p.start()
except:
pass
def sendmessage(self,value):
text = self.myobject.get_object('entry1').get_text()
print text
msg = client.MyClass()
p = multiprocessing.Process(target=msg.run,args=([text]))
p.start()
server.py
//打开一个套接字,监听传入的数据并将其发送回去
import socket,multiprocessing, gtk, sys
class Server:
'''
classdocs
'''
def __init__(self):
'''
Constructor
'''
def run(self):
try:
while 1:
HOST = 'localhost' # Symbolic name meaning the local host
PORT = 50006 # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((HOST, PORT))
s.listen(5)
conn, addr = s.accept()
print 'Connected by', addr
while True:
data = conn.recv(1024)
if not data:
conn.close()
sys.exit()
break
elif data != '':
conn.sendall(data)
break
print "Closing"
#conn.close()
finally:
print "End"
pass
client.py
//将文本区域内的内容发送到套接字
import time
class MyClass:
'''
classdocs
'''
def __init__(self):
'''
Constructor
'''
def run(self,text):
try:
import socket
HOST = 'localhost' # The localhost
PORT = 50006 # The same port as used by the server
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.send(text)
data = s.recv(1024)
while 1:
if data != '':
print 'Received', repr(data)
break
finally:
pass
这是错误的:
p = multiprocessing.Process(target=gtk.main())
p.start()
首先,即使您严格执行gtk主循环,也无法在子进程中启动它。 幸运的是,当您调用 gtk.main()
,该过程从未真正尝试启动main
,它会阻塞直到main循环退出,然后返回None
。 因此,您实际上正在做的是:
gtk.main()
p = multiprocessing.Process(target=None)
p.start()
遍历其余的代码,您将继续创建新流程,然后忘记它们。 如果要保留对它们的引用,则至少可以尝试向它们发送TERM
信号以将其关闭(使用Process.terminate
或设置daemon
标志)。 如果要完全关闭子进程,则需要处理该子mutliprocessing.Event
中的信号 ,或者使用其他IPC机制使其完全关闭(例如mutliprocessing.Event
,...)。
然后是这样的:
while True:
data = conn.recv(1024)
if not data:
conn.close()
sys.exit()
break
elif data != '':
conn.sendall(data)
break
这个while循环永远不会循环(除非recv
神奇地返回一个字符串以外的其他东西)。 第一执行路径结尾sys.exit()
取全服务器向下-断裂不可达),与所述第二端break
,因此该循环是无用的。
以下几行与您完全相反:
data = s.recv(1024)
while 1:
if data != '':
print 'Received', repr(data)
break
除非第一行中的data
为''
,否则这将是一个无休止的循环,因为data
的值将不再更改。
通常,大多数情况下您实际上并不需要多处理。 如果必须要做很多工作,则可以通过其他进程启动服务器,但是为发送一些数据而浪费子进程是过头的。 使用套接字发送和接收是IO绑定的,在这里使用线程会更合理。
您有两个类( Server
和Handler
),它们只有两种方法,一种是__init__
,另一种仅用作子流程的目标:
myserver = server.Server()
try:
p = multiprocessing.Process(target=myserver.run)
和:
msg = client.MyClass()
p = multiprocessing.Process(target=msg.run,args=([text]))
这表明它们不应该是类而是函数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.