python - 为什么 Linux 可以在多进程中接受套接字?

标签 python linux sockets python-multiprocessing

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

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\r\nHost: www.python.org\r\n\r\n")

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) 套接字发送到不同的进程,因此套接字可以在多处理上下文中被 pickle .

多处理模块使用特殊的 pickler 实例而不是常规 pickler,ForkingPickler , 来腌制套接字和文件描述符,然后可以在不同的进程中取消腌制。这样做是唯一可能的,因为它知道 pickle 实例将在哪里被取消 pickle,pickle 套接字或文件描述符并在机器边界之间发送它是没有意义的。

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

关于python - 为什么 Linux 可以在多进程中接受套接字?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40969983/

相关文章:

javascript - AJAX django 获取请求

php - 引用的列名必须是目标实体类上的主键列

linux - 无法使用sudo运行bash脚本

linux - 防止截断共享映射文件?

c# - 我将如何在 ASP.Net 服务器上运行连续任务?

java - 如何通过代理从 HTTPS Url 获取数据?

python - 如何在 python 的日志库中使用捕获操作系统用户的用户名?

python - Pandas:使用 minrank 在 groupby 之后排名

python - 有没有办法让我的不和谐机器人在播放完歌曲后断开与语音 channel 的连接?

c++ - 多连接客户端套接字应用程序C++