我正在開發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