2017-02-03 35 views
0

,當我讀到的代碼redis的-PY(https://github.com/andymccurdy/redis-py/blob/master/redis/connection.py),我瞭解它是如何實現的連接池, 但問題抓住我,我無法理解_checkpid()方法redis-py的connectionPool中_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。任何幫助都是合適的。

回答

1

當一個Unix進程分叉時,它與它的子進程共享已打開的所有套接字。

因此,如果您創建連接池,然後發出請求,然後fork,則會出現問題:在新進程之間複製池本身時,池中的套接字不會被複制並跨流程。

這可能會導致一個進程寫入到redis客戶端,另一個等待回覆將得到錯誤的回覆。

但是,在fork之後新創建的套接字將不會在父級和子級之間共享。

因此,通過檢查pid,池會檢查是否已創建分支,如果是,則重置其所有套接字並創建新分支。這可以防止非常糟糕的事情發生:)

+0

非常感謝您的幫助!但我想不出叉子會發生什麼情況,爲什麼我們需要分叉,並且在我看來,checkpid方法只能阻止你說的話,你能舉個例子嗎? – GuangshengZuo

+0

@ user3013527由於GIL,python無法使用多個CPU。分叉允許Python程序使用多核機器。查看python中的Multiprocessing模塊瞭解更多細節。 https://docs.python.org/3/library/multiprocessing.html –

+0

非常感謝您的幫助! – GuangshengZuo

相關問題