Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/294.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/google-chrome/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python GTK/线程/套接字错误_Python_Multithreading_Sockets_Gtk - Fatal编程技术网

Python GTK/线程/套接字错误

Python GTK/线程/套接字错误,python,multithreading,sockets,gtk,Python,Multithreading,Sockets,Gtk,我正在尝试使用pyGTK、踏板和套接字构建Python应用程序。我有一个奇怪的错误,但是考虑到所有涉及的模块,我不能完全确定错误在哪里。我对一些print语句进行了一些调试,以缩小范围,我认为错误就在这段代码的某个地方: self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock.connect(("localhost", 5005)) self.collectingThread = th

我正在尝试使用pyGTK、踏板和套接字构建Python应用程序。我有一个奇怪的错误,但是考虑到所有涉及的模块,我不能完全确定错误在哪里。我对一些print语句进行了一些调试,以缩小范围,我认为错误就在这段代码的某个地方:

    self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    self.sock.connect(("localhost", 5005))
    self.collectingThread = threading.Thread(target=self.callCollect)
    self.collectingThread.daemon = True
    self.collectingThread.start()

def callCollect(self):
    gobject.timeout_add(500, self.collectData)

def collectData(self):
    print "hello"
    try:
        print self.sock.recv(1024)
    except:
        print "except"
    print "return"
    return True
因此,基本上我要做的是设置一个套接字,连接到一个“服务器”脚本(实际上只是本地运行的另一个python脚本),然后创建一个单独的线程来收集服务器脚本中的所有传入数据。此线程设置为每500毫秒运行一次collectData方法

将print语句插入collectData方法后,我在运行程序时注意到:

-最初,GUI功能齐全

-然后在终端中打印以下内容:

hello
**all data received from server script and printed here**
return
hello
-在终端中打印文本后,GUI将完全失去功能(按钮无法按下等),我必须强制退出以关闭应用程序

似乎正在发生的是线程打印“hello”,打印来自服务器的数据,然后打印“return”。500毫秒后,它再次运行collectData方法,打印“hello”,然后尝试从服务器打印数据。但是,由于没有数据,它会引发异常,但由于未知原因,它不会执行异常块中的代码,所有内容都挂起


知道哪里出了问题吗?

不,显然,
sock.recv
调用会阻塞,因为套接字尚未关闭,默认情况下套接字接收会阻塞。确保在某个点关闭连接

在新线程中运行receive调用更有意义,否则可能会阻塞GUI,因为当前实现在GUI线程中运行
recv
调用(使用
timeout\u add
)。您目前的做法只有在快速收到答案和/或您必须访问小部件时才有意义


顺便说一句,创建一个新线程来调用
gobject.timeout\u add
是完全没有必要的
timeout\u add()
idle\u add()
注册指定的回调函数并立即返回。GTK事件循环会在超时后自动执行回调(或处于空闲状态,用于
idle\u add
)。

否,显然
sock.recv
调用会阻塞,因为套接字尚未关闭,默认情况下套接字接收会阻塞。确保在某个点关闭连接

在新线程中运行receive调用更有意义,否则可能会阻塞GUI,因为当前实现在GUI线程中运行
recv
调用(使用
timeout\u add
)。您目前的做法只有在快速收到答案和/或您必须访问小部件时才有意义


顺便说一句,创建一个新线程来调用
gobject.timeout\u add
是完全没有必要的
timeout\u add()
idle\u add()
注册指定的回调函数并立即返回。GTK事件循环会在超时后自动执行回调(或在空闲状态下执行
idle\u add
)。

timeout\u add
正在调度操作在主线程上发生——因此
recv
只会阻塞主线程(当它只是在等待数据时)以及GUI,因此,除非您设置超时或将套接字设置为非阻塞,否则不会出现异常


您需要将接收任务从计划的操作委派给线程,而不是viceversa,以获得您想要的效果:让线程等待事件对象,计划的动作信号是每500毫秒发生一次事件。

超时\u添加
是计划动作在主线程上发生
——因此,
recv
只会阻塞主线程(当它只是在等待数据时)以及GUI,所以,除非您设置超时或将套接字设置为非阻塞,否则不会出现异常


您需要将接收来自计划操作的消息委派给线程,而不是反之亦然,以获得您想要的效果:让线程(例如,等待事件对象)每隔500毫秒发送一次该事件的计划操作信号。

这是“超时添加”,而不是“超时调用”.我如何明确地告诉次线程等待事件对象及其相应的信号?我查看了pyGTK教程中的不同事件,但在套接字上找不到任何内容。很抱歉,我对pyGTK非常陌生。@pythonBOI,我想到的是Python的
线程
模块,而不是GTK--请看--使用
x=threading.event()
创建全局事件对象
x
,在创建子线程之前,通过调用
x.wait()
,让子线程块等待
x
,让主线程通过
x.set()
(然后通过调用
x.clear()
)唤醒子线程。没有必要的带套接字的连接,也没有GTK的连接,只有通用的Python线程!这是“timeout\u add”,而不是“timeout\u call”。我如何明确地告诉辅助线程等待事件对象及其相应的信号?我查看了pyGTK教程中的不同事件,但在套接字上找不到任何内容。很抱歉,我对pyGTK非常陌生。@pythonBOI,我想到的是Python的
线程
模块,而不是GTK--请看--使用
x=threading.event()
创建全局事件对象
x
,在创建子线程之前,通过调用
x.wait()
,让子线程块等待
x
,让主线程通过
x.set()
(然后通过调用
x.clear()
)唤醒子线程。没有必要的带套接字的连接,也没有GTK的连接,只有通用的Python线程!威尔