0

我正在使用 glade 作为我的 gui 并创建一个进程来运行我的 gui。单击“on”时,此应用程序将打开一个套接字。当我按“发送”时,它会将文本字段中的任何内容发送到套接字。套接字接收此数据并将其发送回。问题是在我将数据发送到套接字后,线程没有终止。同样,在我关闭我的 gui 之后,它会调用 sys.exit() 但也会留下一个进程并且不会终止。我相信错误在于我如何实施我的流程或我的所有处理。任何人都可以对此有所了解吗?这也与我上一篇文章有​​关。谢谢

主文件

// 为我的 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"

处理程序.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()

服务器.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

客户端.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
4

1 回答 1

0

这是错误的:

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

首先,您不能在子进程中启动 gtk 主循环,即使您这样做是正确的。幸运的是,该进程从未真正尝试在main调用 gtk.main()时启动,这将阻塞直到主循环退出然后返回None。所以你实际上在做的是:

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

在您的其余代码中,您不断创建新流程,然后忘记它们。如果您要保留对它们的引用,您至少可以尝试向它们发送TERM信号以关闭它们(使用Process.terminate,或设置daemon标志)。如果你想干净地关闭子进程,你要么需要在子进程中处理那个信号,要么使用其他 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]))

这表明这些不应该是类,而是函数。

于 2013-07-13T16:53:25.570 回答