Four Ways for python to Realize socket Server Concurrency
- 2021-08-28 20:30:06
- OfStack
Multi-process
&
Multithreading
Server side: Multi-process and multi-thread are opened in the same way.
Disadvantages: < 1 > Due to GIL of Cpython, multiple threads cannot be run in the same time; < 2 > It is impossible to enter a process or thread indefinitely
Solution: Multiprocess, concurrent. futures. ProcessPoolExecutor, Thread Pool
import socket
from multiprocessing import Process
from threading import Thread
class MyTcpServer:
def __init__(self, ip, port):
self.ip = ip
self.port = port
self.server = socket.socket()
self.server.bind((self.ip, self.port))
self.server.listen(5)
def wait_accept(self):
conn, addr = self.server.accept()
return conn, addr
def handle_request(self, conn):
while 1:
try:
data = conn.recv(1024)
if not data: break
conn.send(data.upper())
except Exception as e:
print(e)
break
conn.close()
if __name__ == '__main__':
server = MyTcpServer('127.0.0.1', 8888)
while 1:
conn, addr = server.wait_accept()
p = Process(target=server.handle_request, args=(conn, )) # Create 1 Processes
p.start() # Tell the operation to provide and start the process
Process pool
&
Thread pool
Asynchronous submission task, support asynchronous receiving return results (submit returns 1 futures object, call add_done_callback method)
import socket
from concurrent.futures import ProcessPoolExecutor
# from concurrent.futures import ThreadPoolExecutor
class MyTcpServer:
def __init__(self, ip, port):
self.ip = ip
self.port = port
self.server = socket.socket()
self.server.bind((self.ip, self.port))
self.server.listen(5)
def wait_accept(self):
conn, addr = self.server.accept()
return conn, addr
def handle_request(self, conn):
while 1:
try:
data = conn.recv(1024)
if not data: break
conn.send(data.upper())
except Exception as e:
print(e)
break
conn.close()
if __name__ == '__main__':
server = MyTcpServer('127.0.0.1', 8888)
pool = ProcessPoolExecutor(5) # 5 Processes 1 Direct service
while 1:
conn, addr = server.wait_accept()
pool.submit(server.handle_request, conn) # Submit tasks asynchronously
socketserver
Advantages: Simplify socket server creation process.
Serial and concurrent service modes are provided on the server side (TCPServer, ThreadingTCPServer)
Disadvantages: Concurrency cannot be achieved using multiple processes on windows
import socketserver
class MyTcpHandler(socketserver.BaseRequestHandler):
def handle(self): # Communication loop
while 1:
try:
data = self.request.recv(1024)
if not data: break
self.request.send(data.upper())
except Exception as e:
print(e)
break
self.request.close()
if __name__ == '__main__':
ip_port = '127.0.0.1', 8888
server = socketserver.ThreadingTCPServer(ip_port, MyTcpHandler) # Asynchronous processing
server.serve_forever() # Connection loop
Synergetic process
Advantages: Concurrency is realized in a single thread, IO switching is simulated at the code level, and the program running efficiency is improved
from gevent import spawn, monkey;monkey.patch_all() # Monkey patch, patch : Routine IO
import socket
class MyTcpServer:
def __init__(self, ip, port, my_spawn):
self.ip = ip
self.port = port
self.server = socket.socket()
self.server.bind((self.ip, self.port))
self.server.listen(5)
self.spawn = my_spawn # Save spawn Local
def wait_accept(self):
while 1:
conn, addr = self.server.accept()
self.spawn(self.handle_request, conn) # Detection handle_request Adj. io
def handle_request(self, conn):
while 1:
try:
data = conn.recv(1024)
if not data: break
conn.send(data.upper())
except Exception as e:
print(e)
break
conn.close()
if __name__ == '__main__':
server = MyTcpServer('127.0.0.1', 8888, spawn)
g1 = server.spawn(server.wait_accept) # Detection wait_accept Adj. io
g1.join() # Wait g1 End of the run, that is 1 Direct loop detection io
The above is the python implementation of socket server concurrency 4 ways of details, more information about python socket server concurrency please pay attention to other related articles on this site!