我正在编写程序以并行运行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
是一个字符串列表,其中包含下面列出的命令。 Windows上shell
设置为True
,因此shell可以找到可执行文件,因为Windows没有which
命令,并且在Windows上查找可执行文件有点复杂(以前的命令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
是无操作的。)
当客户端冻结时,任务管理器中的内存条会变为空白:
有时一切都会变暗
如果我等待一段时间(几分钟),机器最终会回来。
Q1:并行调用svn
是否是copacetic?
Q2:我使用ThreadPool.map()
和subprocess.Popen()
的方式是否有任何问题?
答案 0 :(得分:0)
我会尽我所能彻底回答所有三个问题,并欢迎更正我的陈述。
Q1:并行调用svn是否是copacetic?
Copacetic,这是有决心的,但我会说它既不推荐也不推荐。使用该语句,源代码控制工具具有需要进程和块级(最佳猜测)锁定的特定功能。校验和,文件传输和文件读/写需要锁定才能正确处理,否则您将面临重复工作和文件争用的风险,这将导致进程失败。
Q2:我使用
ThreadPool.map()
和subprocess.Popen()
的方式是否有任何问题?
虽然我不知道subprocess.Popen()
的绝对细节,因为我在2.6中使用它,但我可以稍微谈谈可编程性。您在创建的代码中所做的是创建一个特定子流程的池,而不是直接调用流程。现在我的头脑中,我对ThreadPool()
的理解是它默认不执行锁定。这可能会导致subprocess.Popen()
出现问题,我不确定。关于我上面的回答,锁定是需要实现的。我建议查看https://stackoverflow.com/a/3044626/2666240以更好地理解线程和池之间的差异,因为我建议使用线程而不是mutliprocessing。由于源控制应用程序的性质需要锁定,如果要在处理锁定时并行操作,则还需要能够同步线程以便不重复工作。几个月前我在Linux上进行了多处理测试,我发现grep正在重复全局搜索。我会看看能否找到我编写的代码并粘贴它。通过线程同步,我希望Python能够以svn能够理解的方式在线程之间传递svn线程状态,以便不会发生进程复制。话虽如此,我不知道svn在这方面是如何工作的,所以我只是猜测/做出最好的猜测。由于svn可能使用相当复杂的锁定方法(我会断言块级锁定而不是inode锁定,但再一次,最好的猜测),实现信号量锁定而不是lock()
或{{1 }}。也就是说,您将不得不通过测试各种锁定和同步方法来确定哪种方法最适合svn。在线程同步方面,这是一个很好的资源:http://effbot.org/zone/thread-synchronization.htm
问题3:是否有调试这类问题的工具/策略?
当然,线程和多处理都应该具有可以与日志记录结合使用的日志记录功能。我只想登录到一个文件,这样你就可以引用一些东西而不仅仅是控制台输出。理论上,您应该只使用Rlock()
并记录所采用的过程。话虽这么说,我不是一个具有线程或多处理功能的日志记录专家,所以其他人可能会比我更好地回答这个问题。
您使用的是Python 2.x还是3.x?