redis-py在退出时不关闭线程

ryhaxcpt  于 2023-08-02  发布在  Redis
关注(0)|答案(3)|浏览(117)

我用的是redis-py 2.10.6和redis 4.0.11。
我的应用程序对数据库和pubsub都使用redis。当我关机时,我经常会被挂起或崩溃。后者通常会抱怨在处理pubsub回调时发生的错误文件描述符或文件上的I/O错误(我没有使用任何),所以我猜基本问题是相同的:不知何故,我没有正确地断开连接,我的redis.Redis对象所使用的池是活的。
前一种错误的输出示例(during _read_from_socket):
redis.exceptions.ConnectionError:从套接字阅读时出错:(9,“错误的文件描述符”)
其他时候,堆栈跟踪清楚地显示redis/connection.py-> redis/client.py-> threading.py,这证明redis没有杀死它使用的线程。
当我星星我运行的应用程序时:

self.redis = redis.Redis(host=XXXX, port=XXXX)
self.pubsub = self.redis.pubsub()
subscriptions = {'chan1': self.cb1, 'chan2': self.cb2}  # cb1 and cb2 are functions
self.pubsub.subscribe(**subscriptions)
self.pubsub_thread = self.pubsub.run_in_thread(sleep_time=1)

字符串
当我想退出应用程序时,我在main中执行的最后一条指令是对我的redis using类中的函数的调用,其实现是:

self.pubsub.close()
self.pubsub_thread.stop()
self.redis.connection_pool.disconnect()


我的理解是,理论上我甚至不需要做任何这些“关闭”电话,然而,有或没有他们,我仍然不能保证一个干净的关闭。
我的问题是,我怎么才能保证一个干净的关闭?

ozxc1zmp

ozxc1zmp1#

我遇到了同样的问题,这主要是由于redis库对关闭的处理不当造成的。在清理过程中,线程继续处理新消息,而不考虑套接字不再可用的情况。在对代码进行了一点搜索之后,我找不到一种方法来防止额外的处理,而不只是等待。
由于这是在关闭阶段运行的,并且它是对第三方库的补救措施,所以我并不过分担心sleep,但理想情况下,应该更新库以防止在关闭时发生进一步的操作。

self.pubsub_thread.stop()
time.sleep(0.5)
self.pubsub.reset()

字符串
这可能值得在redis-py库上发布问题日志或PR。

byqmnocz

byqmnocz2#

PubSubWorkerThread类检查循环内的self._running.is_set()
要执行“干净关机”,您应该调用self.pubsub_thread._running.clean()将线程事件设置为false,然后它将停止。
看看它是如何工作的:https://redis.readthedocs.io/en/latest/_modules/redis/client.html?highlight=PubSubWorkerThread#

yvgpqqbh

yvgpqqbh3#

如果有人遇到这个问题,我有同样的问题,并添加daemon=True作为run_in_thread调用的附加参数。

self.pubsub_thread = self.pubsub.run_in_thread(sleep_time=1, deamon=True)

字符串
这确保了线程不会在程序结束后存活下来,并可能给您提供您正在寻找的干净关机。

相关问题