2013-07-13 40 views
0

我使用glade作爲我的GUI並創建一個進程來運行我的GUI。此應用程序將打開一個套接字,當'點擊'被點擊。當我按'發送'時,它會將任何文本字段發送到套接字。套接字接收這些數據並將其發回。問題是我發送數據到套接字線程不終止後。另外,我關閉我的GUI後,它調用一個sys.exit(),但也離開了一個進程,並沒有終止。我相信錯誤在於我如何實施我的流程或一般的所有處理。任何人都可以對此發光一些?這也與我最後的帖子有關。由於Python終止多處理和優雅的過程

main.py

,創造一個新的進程對我的圖形用戶界面和顯示//主線程它

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空地信號,產生新線程和手柄按鈕和東西

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 

回答

0

這是錯的:

p = multiprocessing.Process(target=gtk.main()) 
p.start() 

首先,你不能在子進程中啓動gtk主循環,即使你做得很好。幸運的是,這個過程永遠不會真的試圖開始main,因爲你需要調用gtk.main(),它將阻塞,直到主循環退出,然後返回None。所以你實際上在做什麼:

​​

通過其餘的代碼,你不斷創建新的過程,然後忘了它們。如果您要保留對它們的引用,您至少可以嘗試發送TERM信號給它們以關閉它們(使用Process.terminate或設置daemon標誌)。如果您想要乾淨地關閉子進程,您可能需要在子進程中使用handle that signal,或者使用其他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綁定,使用線程更合理。

有兩種類(ServerHandler),其僅具有兩個方法,其中之一是__init__,並且另一個僅作爲目標子進程:

myserver = server.Server() 
    try: 
     p = multiprocessing.Process(target=myserver.run) 

和:

msg = client.MyClass() 
    p = multiprocessing.Process(target=msg.run,args=([text])) 

這是一個跡象,這些不應該是類,但功能。