本文介绍了为什么Linux可以在多处理中接受套接字?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此代码在Linux上运行良好,但在Windows下失败(这是意料之中的)。我知道多处理模块使用fork()产生一个新进程,因此父进程(即打开的套接字)拥有的文件描述符由子进程继承。然而,我的理解是,您可以通过多处理发送的唯一类型的数据需要是可拾取的。在Windows和Linux上,Socket对象不可拾取。

from socket import socket, AF_INET, SOCK_STREAM
import multiprocessing as mp
import pickle

sock = socket(AF_INET, SOCK_STREAM)
sock.connect(("www.python.org", 80))
sock.sendall(b"GET / HTTP/1.1
Host: www.python.org

")

try:
    pickle.dumps(sock)
except TypeError:
    print("sock is not pickleable")

def foo(obj):
    print("Received: {}".format(type(obj)))
    data, done = [], False
    while not done:
        tmp = obj.recv(1024)
        done = len(tmp) < 1024
        data.append(tmp)
    data = b"".join(data)
    print(data.decode())


proc = mp.Process(target=foo, args=(sock,))
proc.start()
proc.join()
我的问题是,为什么socket对象,一个明显不可拾取的对象,可以通过多进程传入?它不像Windows那样使用Pickle吗?

推荐答案

在Unix平台上,套接字和其他文件描述符可以使用Unix域(AF_Unix)套接字发送到不同的进程,因此套接字可以在多处理上下文中进行酸洗。

多处理模块使用特殊的Pickler实例而不是常规的PicklerForkingPickler来Pickle套接字和文件描述符,然后可以在不同的进程中取消Pickle。之所以可以这样做,是因为它知道将在何处取消Pickle实例的Pickle,因此没有必要Pickle套接字或文件描述符并在计算机边界之间发送它。

对于Windows,有similar mechanisms用于打开的文件句柄。

这篇关于为什么Linux可以在多处理中接受套接字?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-30 04:33