开始之前,需要先了解一下什么会引起进程阻塞和唤醒的事件
(1)向系统请求共享资源失败。 进程在向系统请求共享资源时,由于系统已无足够的资源分配给它,此时进程因不能继续运行而转变为阻塞状态。
(2)等待某种操作的完成。
当进程启动某种操作后,如果该进程必须在该操作完成之后才能继续执行,则先将该进程阻塞起来以等待操作完成。
(3)新数据尚未达到。
对于相互合作的进程,如果一个进程需要先获得另一个进程提供的数据后才能对该数据进行处理,只要其所需数据尚未到达,进程便只有阻塞。
(4)等待新任务的到达。
在某些操作系统中,特别是在网络环境下的OS,往往设置一些特定的系统进程,每当这种进程完成任务后便把自己阻塞起来,等待新任务的到来。
socket
在建立连接和数据传输的时候,都会存在等待,就是一种阻塞,一次只能服务一个客户端,排队机制,会存在资源的浪费,cpu的浪费,是不可取的
非阻塞套接字
就是将连接和接收的阻塞位置变成错误,再通过try进行捕获错误BlockingIOError,pass掉
try: conn,addr = server.accept() conn.setblocking(False) except BlockingIOError: pass
建立费阻塞套接字的方法是:
套接字.setblocking(False)
用非阻塞创建一个服务端:可同时处理多个客户请求
import socket server = socket.socket() server.setblocking(False) # 设置为非阻塞套接字 server.bind(('', 7790)) server.listen(5) all_conn = [] while True: try: conn, addr = server.accept() conn.setblocking(False) # 新的非阻塞套接字,没有连接会报错 all_conn.append(conn) # 保存记录连接的客户端 except BlockingIOError: # 捕获错误pass掉 pass for conn in all_conn: try: recv_data = conn.recv(1024) if recv_data: print(str(addr) + '>>>' + recv_data.decode()) conn.send(recv_data) else: conn.close() all_conn.remove(conn) except BlockingIOError: pass