我有兩個版本的Python編寫的簡單套接字服務器。 第一個版本使用epoll + nonblocking aproach,並且似乎比阻塞套接字+超時的服務器版本要慢。epoll +非阻塞套接字慢於阻塞+超時?
非阻塞服務器產生10個孩子和孩子在套接字上進行接受。在這種情況下,所有的孩子都得到EPOLLIN通知,但只有一個孩子可以做 接受,所有其他孩子都會得到EAGAIN,這被「除外」忽略。
--- server-nonblocking.py ---
import socket, time, os, select
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(('127.0.0.1', 10000))
sock.listen(512)
sock.setblocking(False)
for _ in range(0,10):
pid = os.fork()
if pid == 0: #in child
poll = select.epoll()
poll.register(sock.fileno(), select.EPOLLIN)
while True:
events = poll.poll(3) # listening for events with 2 sec timeout
for fileno, event in events:
if event & select.EPOLLIN: # there is data on socket available
print("EPOLLIN in PID: " + str(os.getpid()))
try:
clientsock, addr = sock.accept()
clientsock.close()
print("accepted and closed in PID: " + str(os.getpid()))
except:
pass
# we are in parent process, keep it live
while True:
time.sleep(10)
阻塞服務器也滋生10個孩子,但在監聽套接字而是使用超時,超時由except塊攔截並忽略:
--- server-blocking.py ---
import socket, time, os, select
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(('127.0.0.1', 10000))
sock.listen(512)
sock.settimeout(5)
for _ in range(0,10):
pid = os.fork()
if pid == 0: #in child
while True:
try:
clientsock, addr = sock.accept()
clientsock.close()
print("accepted and closed in PID: " + str(os.getpid()))
except:
pass
# we are in parent process, keep it live
while True:
time.sleep(10)
和她e是客戶。它只在環路中連接到服務器並關閉連接。 20秒後。循環將被中斷。
--- client.py ---
import socket, time, select, sys
i = 1
td = time.time()
while True:
print("loop " + str(i) + ", time: " + str(time.time() - td))
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('localhost',10000))
s.setblocking(False)
s.close()
i += 1
if time.time() - td >= 20:
break
這裏是兩臺服務器的結果:
blocking:
loop 137670, time: 19.99994468688965
non-blocking:
loop 94051, time: 19.10340452194214
阻塞服務器可以處理方式比非更多的連接阻止服務器。當客戶端使用非阻塞版本, 我可以看到循環上的一些延遲。
有人可以解釋這種行爲嗎?爲什麼在epoll +非阻塞循環中有一些延遲?
謝謝!