我正在使用SQLAlchemy和multiprocessing。我也使用scoped_session sinse它避免共享相同的會話,但我發現一個錯誤和他們的解決方案,但我不明白爲什麼它會發生。scoped_session中的進程邊界
下面你可以看到我的代碼:
db.py
engine = create_engine(connection_string)
Session = sessionmaker(bind=engine)
DBSession = scoped_session(Session)
script.py
from multiprocessing import Pool, current_process
from db import DBSession
def process_feed(test):
session = DBSession()
print(current_process().name, session)
def run():
session = DBSession()
pool = Pool()
print(current_process().name, session)
pool.map_async(process_feed, [1, 2]).get()
if __name__ == "__main__":
run()
當我運行script.py
輸出是:
MainProcess <sqlalchemy.orm.session.Session object at 0xb707b14c>
ForkPoolWorker-1 <sqlalchemy.orm.session.Session object at 0xb707b14c>
ForkPoolWorker-2 <sqlalchemy.orm.session.Session object at 0xb707b14c>
注意,會話對象是在主過程相同0xb707b14c
和工人(子進程)
,但如果我改變的前兩行的順序運行():
def run():
pool = Pool() # <--- Now pool is instanced in the first line
session = DBSession() # <--- Now session is instanced in the second line
print(current_process().name, session)
pool.map_async(process_feed, [1, 2]).get()
而我跑script.py
再次輸出:
MainProcess <sqlalchemy.orm.session.Session object at 0xb66907cc>
ForkPoolWorker-1 <sqlalchemy.orm.session.Session object at 0xb669046c>
ForkPoolWorker-2 <sqlalchemy.orm.session.Session object at 0xb66905ec>
現在會話實例是不同的。
謝謝!你的解釋非常清楚。但我認爲fork是在這裏做的:'pool.map_async(process_feed,[1,2])。get()' –
@ Overflow012是的,這是一個同樣有效的假設,因爲文檔沒有規定這種或那種方式,但是,作爲實現細節,它在'Pool .__ init__'中發生[https://github.com/python/cpython/blob/5affd23e6f42125998724787025080a24839266e/Lib/multiprocessing/pool.py#L174]。 – univerio