我有一个用Python语言编写的多进程UDP服务器(参见下面的代码).它会正确地产生所需的进程数量.在Linux上,它在不同进程之间正确地负载平衡UDP数据,但在MacOS上,似乎只有一个进程接收数据.我是不是错过了MacOS的一些参数?
from multiprocessing import Pool
import socket
import os
def s(PORT):
UDP_IP = ""
UDP_PORT = PORT
sock = socket.socket(socket.AF_INET, # Internet
socket.SOCK_DGRAM) # UDP
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
sock.bind((UDP_IP, UDP_PORT))
print(f"Started server {os.getpid()}")
while True:
data, addr = sock.recvfrom(1024)
print(f"Received message on {os.getpid()}: {data}")
if __name__ == '__main__':
print(f"Program started {os.getpid()}")
with Pool(5) as p:
p.map(s, [8000] * 5)
(Output MacOS)
Program started 32205
Started server 32233
Started server 32235
Started server 32234
Started server 32232
Started server 32236
Received message on 32233: b'hello 1'
Received message on 32233: b'hello 2'
Received message on 32233: b'hello 3'
Received message on 32233: b'hello 4'
Received message on 32233: b'hello 5'
Received message on 32233: b'hello 6'
Received message on 32233: b'hello 7'
Received message on 32233: b'hello 8'
Received message on 32233: b'hello 9'
Received message on 32233: b'hello 10'
(Output Linux)
Program started 1860163
Started server 1860165
Started server 1860164
Started server 1860166
Started server 1860167
Started server 1860168
Received message on 1860167: b'hello 1'
Received message on 1860165: b'hello 2'
Received message on 1860167: b'hello 3'
Received message on 1860167: b'hello 4'
Received message on 1860164: b'hello 5'
Received message on 1860168: b'hello 6'
Received message on 1860164: b'hello 7'
Received message on 1860167: b'hello 8'
Received message on 1860167: b'hello 9'
Received message on 1860164: b'hello 10'
我也try 了SO_REUSEADDR,但它只启动了一个进程.我猜其他进程正在等待BIND完成,但第一个进程已经掌握了它.
我也try 过用Gingicorn守护进程,但同样的问题也存在,即只有一个工人接收数据.
以下是该程序的一个更简单的版本,带有Gunicorn.
# run with 'gunicorn udp_server --reuse-port -w 5'
import socket
import os
UDP_IP = ""
UDP_PORT = 8001
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
sock.bind((UDP_IP, UDP_PORT))
print(f"Process started {os.getpid()}")
while True:
data, addr = sock.recvfrom(1024)
print(f"Received message ({os.getpid()}): {data}")
Extra:发送UDP数据
for i in `seq 100`; do echo -n "hello $i" | nc -u -w 1 127.0.0.1 8000; done