我正在开发Python中的一个小型irc客户端(版本2.7)。我希望利用多从我目前连接到所有的服务器阅读,但我遇到了一个问题,使用多处理从多个套接字获取信息
import socket
import multiprocessing as mp
import types
import copy_reg
import pickle
def _pickle_method(method):
func_name = method.im_func.__name__
obj = method.im_self
cls = method.im_class
return _unpickle_method, (func_name, obj, cls)
def _unpickle_method(func_name, obj, cls):
for cls in cls.mro():
try:
func = cls.__dict__[func_name]
except KeyError:
pass
else:
break
return func.__get__(obj, cls)
copy_reg.pickle(types.MethodType, _pickle_method, _unpickle_method)
class a(object):
def __init__(self):
sock1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock1.connect((socket.gethostbyname("example.com"), 6667))
self.servers = {}
self.servers["example.com"] = sock1
def method(self, hostname):
self.servers[hostname].send("JOIN DAN\r\n")
print "1"
def oth_method(self):
pool = mp.Pool()
## pickle.dumps(self.method)
pool.map(self.method, self.servers.keys())
pool.close()
pool.join()
if __name__ == "__main__":
b = a()
b.oth_method()
当它击中线pool.map(self.method, self.servers.keys())
我得到的错误
TypeError: expected string or Unicode object, NoneType found
从我读过的内容来看,当我尝试腌制不可挑剔的东西时会发生什么。为了解决这个问题,我首先制作了_pickle_method
和_unpickle_method
,如here所述。然后我意识到我(最初)试图通过pool.map()
套接字列表(非常不可用),因此我将其更改为主机名列表,因为可以对字符串进行酸洗。不过,我仍然遇到这个错误。
然后我试着直接拨打pickle.dumps()
在self.method
,self.servers.keys()
和self.servers.keys()[0]
。正如预期的那样,它的工作罚款后两者,但是从我第一次拿到
TypeError: a class that defines __slots__ without defining __getstate__ cannot be pickled.
一些更多的研究,导致我this question,这似乎表明,这个问题与使用插座(和gnibbler's answer这个问题似乎证实了这一点)。
有没有一种方法可以实际为此使用多处理?从我已经(非常简要地)阅读pathos.multiprocessing
可能是我需要的,但我真的很想坚持标准库,如果可能的话。
我也没有设置使用多处理 - 如果多线程会更好地工作,并避免这个问题,那么我比这些解决方案更开放。
你是否真的试图将一个套接字传递给子进程,还是只是你试图避免的偶然发生的事情?对于前者,你需要迁移套接字,这必须在比Python酸洗更低的层次上完成,并且对于每个平台都是不同的,因为在封面之下,套接字只是文件描述符的包装,而你需要操作系统使相同的文件描述符意味着您的子进程中使用相同的套接字。 – abarnert 2014-09-29 08:20:39
同时,您是否有理由在第一时间使用多处理而不是多线程呢?“从一堆服务器中读取”就像你可以得到I/O约束的范例一样,这正是线程的优点。 – abarnert 2014-09-29 08:21:50
不,我将子进程的字符串键传递给引用套接字的字典。子进程然后使用字符串键来访问套接字,做套接字的东西,然后返回。我使用多处理而不是多线程的原因是因为我是多新的东西,而且我读到python中的线程速度很慢。话虽如此,我对多线程解决方案非常开放 – Dannnno 2014-09-29 08:22:41