并行化svn导致客户端冻结

时间:2014-12-29 10:54:37

标签: python windows svn

我正在编写程序以并行运行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.jobcountmultiprocessing.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是无操作的。)

当客户端冻结时,任务管理器中的内存条会变为空白:

Blacked out memory bar

有时一切都会变暗

Frozen

如果我等待一段时间(几分钟),机器最终会回来。

Q1:并行调用svn是否是copacetic?

Q2:我使用ThreadPool.map()subprocess.Popen()的方式是否有任何问题?

问题3:是否有调试这类问题的工具/策略?

1 个答案:

答案 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?