所以我遇到了一个非常奇怪的错误。我正在为非常基本的TCP服务器制作一个基本的小GUI,但是当我产生进程时,它会返回以下回溯:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python27\lib\lib-tk\Tkinter.py", line 1410, in __call__
return self.func(*args)
File "C:\Users\username\Desktop\localssh\serverv2.py", line 48, in start_server
process.start()
File "C:\Python27\lib\multiprocessing\process.py", line 130, in start
self._popen = Popen(self)
File "C:\Python27\lib\multiprocessing\forking.py", line 271, in __init__
dump(process_obj, to_child, HIGHEST_PROTOCOL)
File "C:\Python27\lib\multiprocessing\forking.py", line 193, in dump
ForkingPickler(file, protocol).dump(obj)
File "C:\Python27\lib\pickle.py", line 224, in dump
self.save(obj)
File "C:\Python27\lib\pickle.py", line 331, in save
self.save_reduce(obj=obj, *rv)
File "C:\Python27\lib\pickle.py", line 419, in save_reduce
save(state)
File "C:\Python27\lib\pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "C:\Python27\lib\pickle.py", line 649, in save_dict
self._batch_setitems(obj.iteritems())
File "C:\Python27\lib\pickle.py", line 681, in _batch_setitems
save(v)
File "C:\Python27\lib\pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "C:\Python27\lib\multiprocessing\forking.py", line 66, in dispatcher
self.save_reduce(obj=obj, *rv)
File "C:\Python27\lib\pickle.py", line 401, in save_reduce
save(args)
File "C:\Python27\lib\pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "C:\Python27\lib\pickle.py", line 548, in save_tuple
save(element)
File "C:\Python27\lib\pickle.py", line 331, in save
self.save_reduce(obj=obj, *rv)
File "C:\Python27\lib\pickle.py", line 419, in save_reduce
save(state)
File "C:\Python27\lib\pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "C:\Python27\lib\pickle.py", line 649, in save_dict
self._batch_setitems(obj.iteritems())
File "C:\Python27\lib\pickle.py", line 681, in _batch_setitems
save(v)
File "C:\Python27\lib\pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "C:\Python27\lib\pickle.py", line 725, in save_inst
save(stuff)
File "C:\Python27\lib\pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "C:\Python27\lib\pickle.py", line 649, in save_dict
self._batch_setitems(obj.iteritems())
File "C:\Python27\lib\pickle.py", line 681, in _batch_setitems
save(v)
File "C:\Python27\lib\pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "C:\Python27\lib\pickle.py", line 725, in save_inst
save(stuff)
File "C:\Python27\lib\pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "C:\Python27\lib\pickle.py", line 649, in save_dict
self._batch_setitems(obj.iteritems())
File "C:\Python27\lib\pickle.py", line 681, in _batch_setitems
save(v)
File "C:\Python27\lib\pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "C:\Python27\lib\pickle.py", line 649, in save_dict
self._batch_setitems(obj.iteritems())
File "C:\Python27\lib\pickle.py", line 681, in _batch_setitems
save(v)
File "C:\Python27\lib\pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "C:\Python27\lib\pickle.py", line 725, in save_inst
save(stuff)
File "C:\Python27\lib\pickle.py", line 286, in save
f(self, obj) # Call unbound method with explicit self
File "C:\Python27\lib\pickle.py", line 649, in save_dict
self._batch_setitems(obj.iteritems())
File "C:\Python27\lib\pickle.py", line 681, in _batch_setitems
save(v)
File "C:\Python27\lib\pickle.py", line 313, in save
(t.__name__, obj))
PicklingError: Can't pickle 'tkapp' object: <tkapp object at 0x02A4C4F0>
我的代码如下:
import SocketServer
import multiprocessing
from Tkinter import *
class MyTCPHandler(SocketServer.BaseRequestHandler):
"""
The RequestHandler class for our server.
It is instantiated once per connection to the server, and must
override the handle() method to implement communication to the
client.
"""
def handle(self):
# self.request is the TCP socket connected to the client
self.data = self.request.recv(1024).strip()
print "{} wrote:".format(self.client_address[0])+str(self.data)
#print self.data
# just send back the same data, but upper-cased
self.request.sendall(self.data.upper())
class Application(object):
def __init__(self):
self.root=Tk()
self.root.resizable(FALSE,FALSE)
self.root.geometry('500x500')
self.root.title("Server GUI")
def set_widgets(self):
self.start_server_button=Button(self.root,text="Start Server",command=self.start_server)
self.end_server_button=Button(self.root,text="Stop Server",command=self.stop_server)
self.logger=Text(self.root,width=50)
def grid_widgets(self):
self.start_server_button.grid(row=1,column=0)
self.end_server_button.grid(row=2,column=0)
self.logger.grid(row=0,column=0)
def configure(self):
pass
def run(self):
self.set_widgets()
self.grid_widgets()
self.configure()
self.root.mainloop()
def start_server(self):
self.logger.insert(END,"Starting process for client.")
process=multiprocessing.Process(target=self.start_serving)
process.start()
def start_serving(self):
HOST, PORT = "localhost", 9999
self.server = SocketServer.TCPServer((HOST, PORT), MyTCPHandler)
self.server.serve_forever()
def stop_server(self):
self.server.shutdown()
if __name__ == "__main__":
Application().run()
答案 0 :(得分:1)
我不完全确定这是否可以解决您的问题,但是,another stackoverflow question可能会找到您正在寻找的答案。您似乎需要将__getstate__()
方法添加到Application
类中。
答案 1 :(得分:1)
PicklingError: Can't pickle 'tkapp' object: <tkapp object at 0x02A4C4F0>
看起来您可能正在尝试共享/发送对象到子进程,但默认情况下,默认情况下,基本上multiprocessing
模块遵循no share
方法,这意味着所有对象被复制并发送到子进程,目标是更容易和更安全的true
多线程系统,但代价是其他方面。
Python使用pickle
模块来序列化对象,因此,如果你不能序列化它,你就不能将它发送到子进程,这是第二个要求,该函数必须是可导入的,因为:
def start_server(self):
self.logger.insert(END,"Starting process for client.")
process=multiprocessing.Process(target=self.start_serving)
process.start()
是一个成员函数,它实际上是不可导入的,多处理试图序列化其所有成员变量,其中大部分都无法序列化,尽管这是一种预感。
你可以试试这个,放在课外。
def start_serving():
HOST, PORT = "localhost", 9999
server = SocketServer.TCPServer((HOST, PORT), MyTCPHandler)
server.serve_forever()
假设您不需要任何进程间通信,那么您可以使用多处理模块中的队列。
这是你启动子流程的方法。
def start_server(self):
self.logger.insert(END,"Starting process for client.")
self.process = multiprocessing.Process(target=start_serving) # make sure you keep a reference of the process.
self.process.start()
然后你可以杀死子进程。
def stop_server(self):
self.process.terminate()
if __name__ == "__main__":
Application().run()
虽然我建议您使用ThreadingMixIn
而不是手动创建子流程,但我不确定它是否使用thread
或process
thread
实际上并不由于GIL而在进程中运行多核计算机。
我测试了它,不幸的是你不能杀掉子进程,serve_forever
似乎阻塞了......
答案 2 :(得分:1)
我遇到了同样的问题:
RewriteCond %{QUERY_STRING} ^debug=1$ [NC]
RewriteRule (.*) app/webroot/$1 [L]
我把它改为:
p=multiprocessing.Process(target=self.targetMethod)
我不再收到EOF错误了。我不明白到底发生了什么。 现在为时已晚,但希望它对某人有所帮助。