Python多处理池挂在地图调用上

wsp*_*irs 10 python mysql multiprocessing

我有一个解析文件的功能,然后使用SQLAlchemy将数据插入MySQL。我一直在按的结果顺序运行该函数,os.listdir()并且一切正常。

因为大部分时间都花在读取文件和写入数据库上,所以我想使用多处理来加快处理速度。这是我的pseduocode,因为实际代码太长:

def parse_file(filename):
    f = open(filename, 'rb')
    data = f.read()
    f.close()

    soup = BeautifulSoup(data,features="lxml", from_encoding='utf-8')

    # parse file here

    db_record = MyDBRecord(parsed_data)

    session.add(db_record)
    session.commit()

pool = mp.Pool(processes=8)

pool.map(parse_file, ['my_dir/' + filename for filename in os.listdir("my_dir")])
Run Code Online (Sandbox Code Playgroud)

我看到的问题是脚本挂起并且永远无法完成。我通常将63条记录中的48条放入数据库。有时更多,有时更少。

我已经尝试过pool.close()并结合使用pool.join(),但似乎都没有帮助。

如何完成此脚本?我究竟做错了什么?我在Linux机器上使用Python 2.7.8。

Pet*_*ood 5

您需要将所有使用多重处理的代码放入其自己的函数中。当多处理在单独的进程中重新导入模块时,这将阻止它递归启动新池:

def parse_file(filename):
    ...

def main():
    pool = mp.Pool(processes=8)
    pool.map(parse_file, ['my_dir/' + filename for filename in os.listdir("my_dir")])

if __name__ == '__main__:
    main()
Run Code Online (Sandbox Code Playgroud)

请参阅有关确保模块可导入的文档,以及有关在Windows(tm)上运行建议


wsp*_*irs 3

问题是两件事的结合:

  1. 我的池代码被多次调用(感谢@Peter Wood)
  2. 我的数据库代码打开了太多会话(和/或)共享会话

我进行了以下更改,现在一切正常: 原始文件

def parse_file(filename):
    f = open(filename, 'rb')
    data = f.read()
    f.close()

    soup = BeautifulSoup(data,features="lxml", from_encoding='utf-8')

    # parse file here

    db_record = MyDBRecord(parsed_data)

    session = get_session() # see below
    session.add(db_record)
    session.commit()

pool = mp.Pool(processes=8)

pool.map(parse_file, ['my_dir/' + filename for filename in os.listdir("my_dir")])
Run Code Online (Sandbox Code Playgroud)

数据库文件

def get_session():
    engine = create_engine('mysql://root:root@localhost/my_db')

    Base.metadata.create_all(engine)
    Base.metadata.bind = engine

    db_session = sessionmaker(bind=engine)

    return db_session()
Run Code Online (Sandbox Code Playgroud)