python2,socket多進程的錯誤pickle.PicklingError: Can't pickle


python2,socket多進程的錯誤pickle.PicklingError: Can't pickle

源碼:
#coding:utf-8
import socket
import pickle
from multiprocessing import Process

HTML_ROOT_DIR = ""

def handle_client(client_socket):
    """處理客戶端請求"""
# 獲取客戶端請求數據
request_data = client_socket.recv(1024)
    print("request data:",request_data)

    # 構造響應數據
response_start_line = "HTTP/1.1 200 OK\r\n"
    response_headers = "Server:My server\r\n"
    response_body = "hello lijizne"
    response = response_start_line + response_headers + "\r\n" + response_body
    print("response data:",response)

    # 向客戶端返回響應數據
client_socket.send(response)

    # 關閉客戶端
client_socket.close()

if __name__ == "__main__":
    server_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    server_socket.bind(("",8000))
    server_socket.listen(128)

    while True:
        client_socket,client_address = server_socket.accept()
        # print("[%s, %s]用戶連接上了" % (client_address[0],client_address[1]))
print("[%s, %s]用戶連接上了" % client_address)
        handle_client_process = Process(target=handle_client,args=(client_socket,))
        handle_client_process.start()
        client_socket.close()

 

報錯:

Traceback (most recent call last):
  File "F:/pythontest/pythonsocket/01_static_web_server.py", line 37, in <module>
    handle_client_process.start()
  File "E:\Python2\lib\multiprocessing\process.py", line 130, in start
    self._popen = Popen(self)
  File "E:\Python2\lib\multiprocessing\forking.py", line 277, in __init__
    dump(process_obj, to_child, HIGHEST_PROTOCOL)
  File "E:\Python2\lib\multiprocessing\forking.py", line 199, in dump
    ForkingPickler(file, protocol).dump(obj)
  File "E:\Python2\lib\pickle.py", line 224, in dump
    self.save(obj)
  File "E:\Python2\lib\pickle.py", line 331, in save
    self.save_reduce(obj=obj, *rv)
  File "E:\Python2\lib\pickle.py", line 419, in save_reduce
    save(state)
  File "E:\Python2\lib\pickle.py", line 286, in save
    f(self, obj) # Call unbound method with explicit self
  File "E:\Python2\lib\pickle.py", line 649, in save_dict
    self._batch_setitems(obj.iteritems())
  File "E:\Python2\lib\pickle.py", line 681, in _batch_setitems
    save(v)
  File "E:\Python2\lib\pickle.py", line 286, in save
    f(self, obj) # Call unbound method with explicit self
  File "E:\Python2\lib\pickle.py", line 548, in save_tuple
    save(element)
  File "E:\Python2\lib\pickle.py", line 331, in save
    self.save_reduce(obj=obj, *rv)
  File "E:\Python2\lib\pickle.py", line 419, in save_reduce
    save(state)
  File "E:\Python2\lib\pickle.py", line 286, in save
    f(self, obj) # Call unbound method with explicit self
  File "E:\Python2\lib\pickle.py", line 548, in save_tuple
    save(element)
  File "E:\Python2\lib\pickle.py", line 286, in save
    f(self, obj) # Call unbound method with explicit self
  File "E:\Python2\lib\pickle.py", line 649, in save_dict
    self._batch_setitems(obj.iteritems())
  File "E:\Python2\lib\pickle.py", line 681, in _batch_setitems
    save(v)
  File "E:\Python2\lib\pickle.py", line 286, in save
    f(self, obj) # Call unbound method with explicit self
  File "E:\Python2\lib\pickle.py", line 748, in save_global
    (obj, module, name))
pickle.PicklingError: Can't pickle <built-in method recvfrom_into of _socket.socket object at 0x0000000002562370>: it's not found as __main__.recvfrom_into

 

解決:

在stackoverflow上找到了答案,是因為windows操作系統的原因,在Windows中,多進程multiprocessing使用的是序列化pickle來在多進程之間轉移數據,而socket對象是不能被序列化的,但是在linux操作系統上卻沒問題,因為在linux上多進程multiprocessing使用的是fork,所以在windows上可以改用多線程。因為網絡通信屬於io密集型的操作,對cpu計算要求不高,不用多進程,用多線程就行。

 

參考資料:

https://stackoverflow.com/questions/33064982/how-can-i-shred-socket-object-over-python-multiprocess-it-raises-eoferror

https://github.com/dpkp/kafka-python/issues/46

https://docs.python.org/2/library/multiprocessing.html#windows

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM