我有一个解析文件的函数,并使用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")])
我看到的问题是脚本挂起并且永远不会完成。我通常会将63条记录中的48条记录到数据库中。有时它更多,有时它更少。
我已尝试使用pool.close()
并与pool.join()
结合使用,似乎没有任何帮助。
如何完成此脚本?我究竟做错了什么?我在Linux机器上使用Python 2.7.8。
答案 0 :(得分:3)
您需要将所有使用多处理的代码放在其自己的函数中。当多处理在单独的进程中重新导入模块时,这会阻止它以递归方式启动新池:
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()
请参阅有关making sure your module is importable的文档,以及advice for running on Windows(tm)
答案 1 :(得分: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")])
数据库文件
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()