因此,我try 构建以下设置:

  • 拥有一个通过新线程处理传入连接的TCP服务器,
  • 具有另一个进程,该进程创建连接到该TCP服务器的新进程(TCP客户端).

我在Windows 10笔记本电脑上使用的是Python3.11.2.

在大多数情况下,它都运行得很好.我只是偶尔会遇到与TCP客户端进程有关的问题.问题是有些进程不会被创建.这不能一直重现,有时我在创建5个客户端进程时会遇到问题,有时在创建150个时运行得很顺利.Tcp服务器socket.listen()Backlog已经足够高了.

服务器代码

import threading
import socket

MAX_DATASIZE = 2048;

HOST = "127.0.0.1"
PORT = 5000

def handleSingleSocket(conn, addr):
    print("Client "+ str(addr[0]) + ": " + str(addr[1]) + " connected")
    data = conn.recv(MAX_DATASIZE)
    print(data)
    conn.sendall(data)
    conn.close()
    print("Client "+ str(addr[0]) + ": " + str(addr[1]) + " disconnected")

listSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
listSocket.bind((HOST, PORT))
listSocket.listen(200)
print(f"Server listening on address {HOST} and port {PORT}")

while True:
    conn, addr = listSocket.accept()
    thread = threading.Thread(target=handleSingleSocket,args=(conn,addr))
    thread.start()
    print(f"[ACTIVE CONNECTIONS]: {threading.active_count() - 1}" )

客户端代码(Hibernate 是让所有客户端同时连接)

import socket
import multiprocessing
import time

MAX_DATASIZE = 2048;
HOST = "127.0.0.1"
PORT = 5000

def handleSingleConnection(sock: socket.socket, i):
    sock.connect((HOST, PORT))
    time.sleep(2)
    sock.sendall(f"Hello from Process {i}!".encode())
    result = sock.recv(MAX_DATASIZE)
    print(result)
    sock.close()

if (__name__ == '__main__'):
    for i in range(150):
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        process = multiprocessing.Process(target=handleSingleConnection, args=(sock,i,))
        process.start()

有些连接不会被创建.错误代码如下所示:

Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "C:\Users\erath\AppData\Local\Programs\Python\Python311\Lib\multiprocessing\spawn.py", line 120, in spawn_main 
    exitcode = _main(fd, parent_sentinel)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\erath\AppData\Local\Programs\Python\Python311\Lib\multiprocessing\spawn.py", line 130, in _main      
    self = reduction.pickle.load(from_parent)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\erath\AppData\Local\Programs\Python\Python311\Lib\multiprocessing\reduction.py", line 238, in _rebuild_socket
    return ds.detach()
           ^^^^^^^^^^^
  File "C:\Users\erath\AppData\Local\Programs\Python\Python311\Lib\multiprocessing\resource_sharer.py", line 38, in detach
    with _resource_sharer.get_connection(self._id) as conn:
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\erath\AppData\Local\Programs\Python\Python311\Lib\multiprocessing\resource_sharer.py", line 86, in get_connection
    c = Client(address, authkey=process.current_process().authkey)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\erath\AppData\Local\Programs\Python\Python311\Lib\multiprocessing\connection.py", line 499, in Client    c = PipeClient(address)
        ^^^^^^^^^^^^^^^^^^^
  File "C:\Users\erath\AppData\Local\Programs\Python\Python311\Lib\multiprocessing\connection.py", line 701, in PipeClient
    _winapi.WaitNamedPipe(address, 1000)
FileNotFoundError: [WinError 2] Das System kann die angegebene Datei nicht finden

因此,我猜这与Windows上进程的衍生创建有关,但我真的无法理解它.非常感谢您的帮助,提前谢谢!:)

推荐答案

https://superfastpython.com/filenotfounderror-multiprocessing-python/

在这篇文章的帮助下,我能够解决这个问题.

显然,主函数在子进程之前退出,因此无法找到库中的文件.

文章定义了这种行为的三个前提条件:

  1. 使用"派生"启动方法来创建新进程.
  2. 与一个或多个进程共享并发基元.
  3. 主进程在子进程完全启动之前退出.

有趣的是,我没有使用并发原语,仍然面临这个问题.

在启动前将进程附加到一个列表中,然后在它们在main函数中执行后加入它们,就可以做到这一点.

if __name__ == '__main__':
    plist = []
    for i in range(200):
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        process = multiprocessing.Process(target=handleSingleConnection, args=(sock,i))
        plist.append(process)
        process.start()
    for p in plist:
        p.join()

Python相关问答推荐

Python -根据另一个数据框中的列编辑和替换数据框中的列值

剧作家Python没有得到回应

Class_weight参数不影响RandomForestClassifier不平衡数据集中的结果

我必须将Sigmoid函数与r2值的两种类型的数据集(每种6个数据集)进行匹配,然后绘制匹配函数的求导.我会犯错

PywinAuto在Windows 11上引发了Memory错误,但在Windows 10上未引发

删除所有列值,但判断是否存在任何二元组

大小为M的第N位_计数(或人口计数)的公式

NP.round解算数据后NP.unique

在np数组上实现无重叠的二维滑动窗口

如何让这个星型模式在Python中只使用一个for循环?

如何在Polars中从列表中的所有 struct 中 Select 字段?

连接一个rabrame和另一个1d rabrame不是问题,但当使用[...]'运算符会产生不同的结果

Pandas Data Wrangling/Dataframe Assignment

在matplotlib中使用不同大小的标记顶部添加批注

如何获取Python synsets列表的第一个内容?

基于多个数组的多个条件将值添加到numpy数组

如何在Great Table中处理inf和nans

裁剪数字.nd数组引发-ValueError:无法将空图像写入JPEG

如何防止html代码出现在quarto gfm报告中的pandas表之上

如何在Django模板中显示串行化器错误