2013-07-13 3 views
0

Я использую glade как мой gui и создаю процесс для запуска моего gui. Это приложение откроет сокет, когда будет нажата кнопка «on». Когда я нажимаю 'send', он отправляет все, что находится в текстовое поле в сокет. Сокет получает эти данные и отправляет их обратно. Проблема заключается в том, что после отправки данных в сокет поток не завершается. Также после того, как я закрыл свой gui, он вызывает sys.exit(), но также оставляет процесс и не завершает работу. Я считаю, что ошибка заключается в том, как я реализую свои процессы или всю мою обработку в целом. Может ли кто-нибудь осветить этот свет? Это также относится и к моему последнему сообщению. БлагодаряPython завершает многопроцессорную обработку и процесс gui изящно

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. Так что вы на самом деле делаете:

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

Througout остальная часть кода вы продолжаете создавать новые процессы, а затем забыть о них. Если вы сохраните ссылку на них, вы можете хотя бы попытаться отправить сигнал 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 

Это в то время как петля никогда не будет цикл (если recv волшебно не возвращает что-то другое, то строку). Первый путь выполнения заканчивается sys.exit() (снятие всего сервера вниз - разрыв недоступен), второй заканчивается break, поэтому цикл бесполезен.

Несколько строк ниже вас есть прямо противоположное:

 data = s.recv(1024) 
     while 1: 
      if data != '': 
       print 'Received', repr(data) 
       break 

Если data не был '' в первой строке, это будет бесконечный цикл, так как значение data «s не изменится больше.

Как правило, вам не нужна многопроцессорная обработка для большей части этого. Запуск сервера в другом процессе может быть оправданным, если он должен выполнять большую работу, но отладка подпроцесса просто для отправки некоторых данных является излишним. Отправка и получение с использованием сокетов связаны с 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])) 

Это знак того, что это не классы, а функции.

Смежные вопросы