[英]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.