Epoll+线程池工作原理
时间: 2023-12-01 10:42:44 浏览: 97
Epoll+线程池的工作原理如下:
1. 单线程创建epoll并等待,有I/O请求(socket)到达时,将其加入epoll并从线程池中取一个空闲工作者线程,将实际的业务交由工作者线程处理。
2. 当多个任务到来时,Epoll及时响应并将任务下发给特定的处理线程,完成对应的任务。
3. 如果只用单线程进行listen轮询监听的话,效率上实在是太低。而借助epoll的话就会很完美的解决这个问题。
4. 使用线程池的缘由是为了避免频繁创建和销毁线程,提高线程的复用率和效率。
代码示例:
```python
import socket
import threading
import queue
import select
# 定义线程池类
class ThreadPool:
def __init__(self, max_workers):
self.max_workers = max_workers
self._workers = []
self._task_queue = queue.Queue()
self._init_workers()
# 初始化线程池
def _init_workers(self):
for i in range(self.max_workers):
worker = threading.Thread(target=self._worker)
worker.start()
self._workers.append(worker)
# 工作者线程
def _worker(self):
while True:
try:
func, args, kwargs = self._task_queue.get()
func(*args, **kwargs)
except Exception as e:
print(e)
# 提交任务
def submit(self, func, *args, **kwargs):
self._task_queue.put((func, args, kwargs))
# 定义服务端类
class Server:
def __init__(self, host, port, max_workers):
self.host = host
self.port = port
self.max_workers = max_workers
self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.server_socket.bind((self.host, self.port))
self.server_socket.listen(5)
self.thread_pool = ThreadPool(self.max_workers)
# 处理客户端请求
def handle_request(self, client_socket, client_address):
print(f"Connected by {client_address}")
while True:
data = client_socket.recv(1024)
if not data:
break
client_socket.sendall(data)
client_socket.close()
# 运行服务端
def serve_forever(self):
print(f"Server is running on {self.host}:{self.port}")
while True:
client_socket, client_address = self.server_socket.accept()
self.thread_pool.submit(self.handle_request, client_socket, client_address)
# 运行服务端
if __name__ == '__main__':
server = Server('localhost', 8888, 10)
server.serve_forever()
```
阅读全文