当我读取redis-py(https://github.com/andymccurdy/redis-py/blob/master/redis/connection.py)的代码时,我学习了它如何实现连接池, 但是一个问题困扰着我,我无法理解_checkpid()方法
def _checkpid(self):
if self.pid != os.getpid():
with self._check_lock:
if self.pid == os.getpid():
# another thread already did the work while we waited
# on the lock.
return
self.disconnect()
self.reset()
请原谅我无法复制连接池的所有代码。这是我的想法,当它从池或发布到池,它将检查pid,我不明白为什么。如果它在多进程中运行,则不需要锁定 它将有许多相同的池。如果它在多线程中运行,它将始终获得相同的pid。任何帮助都是适当的。
答案 0 :(得分:2)
当Unix进程分叉时,它会与其子进程共享已在其中打开的所有套接字。
因此,如果您创建连接池,然后发出请求,然后执行fork,则会出现问题:虽然池本身会在新进程之间复制,但池中的套接字不会被复制并在进程间共享。
这可能导致一个进程写入redis客户端的情况,另一个等待回复的情况将得到错误的回复。
但是,在fork之后新创建的套接字将不会在父级和子级之间共享。
因此,通过检查pid,池会检查是否已经创建了fork,如果是,则重置其所有套接字并创建新套接字。这可以防止非常糟糕的事情发生:)