为什么psycopg2通知监听循环需要判断连接是否可读?
问题解答
1. select.select([conn],[],[],5) == ([],[],[])的作用
select是Python标准库中实现IO多路复用的函数,调用时传入的四个参数分别代表:
- 第一个列表:要监听是否可读的IO对象列表,这里只传入了psycopg2的数据库连接对象
- 第二、第三个列表:分别是要监听是否可写、是否异常的IO对象列表,这里不需要所以传空
- 第四个参数:超时时间,单位为秒,这里设置为5秒
select的返回值是三个列表,分别对应就绪的可读、可写、异常IO对象。如果返回([],[],[]),说明5秒内连接上没有任何待处理的IO事件,触发超时逻辑。所以这条判断语句的作用就是:
检测5秒内数据库连接是否有事件到达,超时无事件则执行超时分支打印
Timeout,有事件则进入后续通知处理流程。这种写法相比空循环轮询通知队列,可以避免无效占用CPU资源,同时超时设置也给程序预留了响应其他信号、执行其他定时任务的空间。
2. psycopg2连接处于「可读」状态的具体含义
psycopg2的连接对象实现了fileno()方法,本质上是对连接PostgreSQL的底层TCP套接字的封装,所以传入select监听的「可读」状态,就是指这个底层TCP套接字可读,具体对应场景包括:
- 收到PostgreSQL服务端主动推送的NOTIFY通知事件
- 之前提交到服务端的SQL语句执行完成,服务端返回了结果
- 服务端主动断开连接、网络异常等TCP层面的事件
要注意的是:套接字可读不代表一定收到了NOTIFY通知,所以后续必须调用conn.poll()来解析连接上的所有待处理数据,把解析完成的通知事件写入conn.notifies队列后,再遍历队列处理通知,才能保证逻辑正确。
内容的提问来源于stack exchange,提问作者fgregg
相关产品推荐
相关产品推荐

