我正在编写一个程序来并行运行svn up
,并导致机器冻结。 发生这种情况时服务器没有遇到任何负载问题。
使用ThreadPool.map()
将命令运行到subprocess.Popen()
:
def cmd2args(cmd): if isinstance(cmd, basestring): return cmd if sys.platform == 'win32' else shlex.split(cmd) return cmd def logrun(cmd): popen = subprocess.Popen(cmd2args(cmd), stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=curdir, shell=sys.platform == 'win32') for line in iter(popen.stdout.readline, ""): sys.stdout.write(line) sys.stdout.flush() ... pool = multiprocessing.pool.ThreadPool(argv.jobcount) pool.map(logrun, _commands)
argv.jobcount
是multiprocessing.cpu_count()
和要运行的作业数量(在本例中为4)中的较小者。 _commands
是下面列出的命令的string列表。 shell
在Windows上设置为True
,所以shell可以find可执行文件,因为Windows没有一个命令,在Windows上查找一个可执行文件比较复杂(命令的forms是cd directory&&svn up ..
需要shell=True
但现在用cwd
参数来完成)。
正在运行的命令是
svn up w:/srv/lib/dktabular svn up w:/srv/lib/dkmath svn up w:/srv/lib/dkforms svn up w:/srv/lib/dkorm
其中每个文件夹是一个单独的项目/存储库,但存在于同一个Subversion服务器上。 svn
可执行文件是与TortoiseSVN 1.8.8(build 25755 – 64 Bit)打包在一起的。 代码是最新的(即svn up
是一个没有操作)。
当客户端冻结时,任务pipe理器中的内存条首先变为空白:
有时候一切都变黑了
如果我等了一会儿(几分钟),机器最终会回来。
Q1:并行调用svn
是否同时出现?
Q2:我是如何使用ThreadPool.map()
和subprocess.Popen()
?
问题3:有没有debugging这些问题的工具/策略?
我将尽我所能,全面回答这三个问题,并欢迎对我的发言进行更正。
Q1:并行调用svn是否同时出现?
Copacetic,这是决心,但我会说,既不推荐也不推荐。 有了这个声明,源代码控制工具就具有特定的功能,需要进程和块级(最佳猜测)锁定。 校验和,文件传输和文件读/写需要锁定才能正确处理,否则可能会导致重复工作和文件争用,从而导致进程失败。
Q2:我是如何使用
ThreadPool.map()
和subprocess.Popen()
?
虽然我不知道subprocess.Popen()
的绝对细节,但是我在2.6中使用了它,所以我可以稍微讲一下可编程性。 您在创建的代码中所做的是创建一个特定子进程的池,而不是直接调用进程。 现在关闭我的脑海,并且我对ThreadPool()
理解是它默认不会执行锁定。 这可能会导致subprocess.Popen()
问题subprocess.Popen()
,我不知道。 关于上面的答案,锁定是需要实施的。 我会建议看看https://stackoverflow.com/a/3044626/2666240更好地理解线程和池之间的差异,因为我会建议使用线程,而不是mutliprocessing。 由于需要锁定的源控制应用程序的性质,如果要在处理锁定时并行操作,还需要能够同步这些线程,以便不会重复工作。 几个月前,我在Linux上运行了一个多处理测试,我发现grep正在重复全局搜索。 我会看看我是否可以找到我写的代码并粘贴它。 通过线程同步,我希望Python能够以svn能够理解的方式在线程之间传递svn线程状态,以避免进程重复。 话虽如此,我不知道svn是如何在这方面发挥作用的,所以我只是猜测/猜测。 由于svn可能使用了一个相当复杂的锁定方法(我会断言块级锁定,而不是inode锁定,但再一次,最好的猜测),实现信号量锁定而不是lock()
或Rlock()
可能是有意义的。 也就是说,你将不得不通过和测试各种锁定和同步方法来找出最适合svn的方法。 说到线程同步,这是一个很好的资源: http : //effbot.org/zone/thread-synchronization.htm
问题3:有没有调试这些问题的工具/策略?
当然,线程和多处理应该都具有日志记录功能,您可以结合使用日志记录功能。 我只是登录到一个文件,以便您可以有一些引用,而不是只是控制台输出。 理论上,您应该只能使用logging.debug(pool.map(logrun, _commands))
并记录所采用的进程。 也就是说,我不是线程或多处理的测井专家,所以别人可能会比我更好地回答这个问题。
你正在使用Python 2.x或3.x?