alexlip
V2EX  ›  Python

求解惑, Python 多进程问题

By alexlip at 2020 年 1 月 9 日 · 4068 次点击

需求:多进程使用 mysqldump 分表逻辑备份 mysql.

开始使用 gnu parallel 来进行多进程备份,发现如果有一个进程备份时间久的话,会卡住已完成的进程等待这个进程. 不太了解 prarllel,所以考虑用 python multiprocessing.pool 来管理进程,目的是尽快的分配任务让多核来完成任务. if name == 'main': result = list() with open(sys.argv[1],'r') as o: lines = csv.reader(o) for line in lines: result.append(line) p = Pool(5) for i in result: p.apply_async(run,(i,)) p.close() p.join()

使用以上方式直接创建 pool,在 run 里使用 os.system 调用 mysqldump 执行备份工作.测试发现, 1234 进程已经完成备份,5 还未完成. 在这种情况下,1234 进程在等待 5 的完成, 并不是理想中的继续接任务执行.

求解惑,这是什么情况? 如何能实现我的需求. 如果用 queue 在 run 函数中读取队列,能否实现?

16 条回复  •  2020-01-13 09:58:00 +08:00
ipwx
   1
ipwx  
   2020 年 1 月 9 日
如果你只有五个任务,那么 1234 跑完等第 5 个不是很合适么。。。

你这需求都没有描述清楚,而且排版乱七八糟。
alexlip
   2
alexlip  
OP
   2020 年 1 月 9 日
@ipwx 不好意思. 发的时候是正常的[哭] ...
实际任务有 100 多, 开了 10 个进程.
所以我想问的是, 一批次执行 10 个任务的情况下, 是要等待 10 个任务完成,才会进行后续的任务吗?
wuwukai007
   3
wuwukai007  
   2020 年 1 月 9 日 via Android
os.system 是阻塞的,就算开进程池也没用,5 个进程也在等待,用线程把 os.system 包起来
alexlip
   4
alexlip  
OP
   2020 年 1 月 9 日
@wuwukai007 我理解 os.system 是阻塞的, 我的想法是等 os.system("mysqldump") 执行完毕,再继续执行任务.
我的问题是 5 个 os.system 4 个已经完成, 并没有继续接受新的任务执行.而是在等待第 5 个执行结束
ipwx
   5
ipwx  
   2020 年 1 月 9 日 via Android
你这就是你的全部代码么? 如果不是,请原样发上来。另外其实 thread 就能搞定不需要 process,毕竟你是调用了 os.system
alexlip
   6
alexlip  
OP
   2020 年 1 月 9 日
不知道怎么编辑追加帖子. 只能再回复里写了.

100 个需要执行的任务, 开 10 进程. 使用 Pool, 期望实现哪个进程空闲哪个进程执行任务.因为表有大小,执行时长不同.现在的情况是 123456789 执行完毕, 10 还在执行. 123456789 并没有继续接任务执行,而是在等待 10 的完成. 在 10 完成后才会接后面的 10 个任务同时开始执行. 我怎么才能实现 123456789 不等待 10, 直接继续后续任务?
ipwx
   7
ipwx  
   2020 年 1 月 9 日 via Android
@alexlip 我说的是你的代码!代码!鬼知道你怎么写的代码出了你说的问题,我现在只能回答你,用 pool 可以不阻塞在第十个任务上
alexlip
   8
alexlip  
OP
   2020 年 1 月 9 日
```def run(dbtab):
folder='/home/www/dbbak/'+time.strftime("%Y%m%d",time.localtime())
cmd = "/home/www/mysql-5.7.12/bin/mysqlpump --host 127.0.0.1 -uwww --include-databases={0} --include-tables={1} --skip-watch-progress --compress-output=LZ4 > {2}/{0}/{1}.sql.lz4".format(dbtab[0],dbtab[1],folder)
os.system(cmd)

if __name__ == '__main__':
result = list()
with open(sys.argv[1],'r') as o:
lines = csv.reader(o)
for line in lines:
result.append(line)
p = Pool()
for i in result:
p.apply_async(run,(i,))
p.close()
p.join()
```
alexlip
   9
alexlip  
OP
   2020 年 1 月 9 日
@ipwx 代码很简单,已经贴上了,你帮忙看下?
wuwukai007
   10
wuwukai007  
   2020 年 1 月 9 日
用线程池直接开 50 个,一样的
ipwx
   11
ipwx  
   2020 年 1 月 9 日
@alexlip 我只能说你代码是对的。不信你可以把这段代码放到你自己机器上执行一下:

https://ideone.com/Ety65q
ipwx
   12
ipwx  
   2020 年 1 月 9 日
至少 Python 层面的代码是没问题的。
ipwx
   13
ipwx  
   2020 年 1 月 9 日
实在不行你手搓一个多线程试试呗,给你个 demo:

https://ideone.com/mK2PfL
alexlip
   14
alexlip  
OP
   2020 年 1 月 9 日
@ipwx 好的,谢谢. 我去测试个试试
leishi1313
   15
leishi1313  
   2020 年 1 月 10 日
更多像是 mysqldump 的问题而不是 python 的问题
aaronhua
   16
aaronhua  
   2020 年 1 月 13 日
推荐学习书目
› Learn Python the Hard Way
Python Sites
› PyPI - Python Package Index
› http://diveintopython.org/toc/index.html
› Pocoo
值得关注的项目
› PyPy
› Celery
› Jinja2
› Read the Docs
› gevent
› pyenv
› virtualenv
› Stackless Python
› Beautiful Soup
› 结巴中文分词
› Green Unicorn
› Sentry
› Shovel
› Pyflakes
› pytest
Python 编程
› pep8 Checker
Styles
› PEP 8
› Google Python Style Guide
› Code Style from The Hitchhiker's Guide
© 2026 V2EX · 33ms · 3.9.8.5