线程或多处理如何与递归一起工作?

时间:2011-09-23 21:43:21

标签: python multithreading algorithm scalability multiprocessing

背景

我对开发有点新意,并且有一个普通的python /编程问题。如果您有一个递归方法,启用多个线程或多处理涉及什么?我已经完成了一些简单的阅读和一些示例,但它们似乎正在应用新代码的语法(而不是非常密集的任务),我更想知道如何重新设计现有代码来执行此操作?

说我有一些cpu密集的东西(基本上一直在添加自己,直到达到限制):

def adderExample(sum, number):
    if sum > 1000:
        print 'sum is larger than 10. Stoping'
    else:
        sum = sum + number
        print sum
        number = number + 1
        adderExample(sum, number)


adderExample(0,0)

问题/虽然流程

如果我有多个核心可用,我将如何处理它以使其运行更快(我希望它最终希望它跨越机器但我认为这是hadoop的sperate问题所以我将这个例子保留到只有一个系统多个cpu的)?似乎线程它不是最好的选择(因为产生新线程所需的时间),如果那是真的我应该只专注于多处理?如果是这样,可以将递归拆分为不同的cpu(我假设的vai队列,然后在完成后重新加入)?我可以为每个进程创建多个线程,而不是将这些进程分成多个cpu吗?最后,递归深度限制了一个总体限制,还是基于线程/过程,如果是这样,多处理/线程会绕过它?

另一个问题(相关)这些家伙如何通过暴力破解这个问题来尝试编码(rsa,无线密钥等)?我假设他们正在以某种方式在多个cpu上扩展他们的数学过程。这个或任何建立我的理解的例子都会很棒。

任何提示/建议都会很棒

谢谢!

3 个答案:

答案 0 :(得分:4)

这样的循环根本不会从线程中获益太多。考虑您正在进行一系列添加,其中间值取决于先前的迭代。这不能并行化,因为线程会踩在彼此的值上并覆盖事物。您可以锁定数据,这样一次只有一个线程可以处理它,但是你会失去让多个线程处理这些数据的好处。

线程在拥有独立数据集时效果最佳。例如图形渲染器就是一个很好的例子。每个线程渲染较大图像的子集 - 它们可以共享纹理/顶点/颜色/等等数据的公共数据源,但是每个线程都有自己的整个图像的一小部分可以工作一个,并且不会触摸图像的其他区域。无论线程#1在其小部分像素上做什么都不会影响#2在图像中的其他位置做什么。

对于您的相关问题,密码破解是线程/多处理有意义的另一个示例。每个线程自行测试多个可能的密码,针对一个常见的“待破解”列表。一个线程正在做的事情不会影响任何其他的cracker线程,除非你得到一个匹配,这可能意味着所有线程都会因为工作“完成”而中止。

一旦线程彼此相互依赖,您就会失去拥有多个线程的许多好处。他们会花更多的时间等待对方完成,而不是花在做实际工作上。当然,这并不是说你永远不应该使用线程。有时,拥有多个线程确实有意义,即使它们是相互依赖的。例如。图形线程+音效线程+动作处理器线程+ A.I.计算线程等...在游戏中。每一个名义上都是相互依赖的,但是当声音线程忙着为玩家刚开枪的枪发出爆炸+弹跳音频时,a.i.线程是关闭计算游戏的怪物正在做什么,图形线程在背景中绘制一些云等...

答案 1 :(得分:1)

Threading kinda sorta意味着多个堆栈,递归单个堆栈。也就是说,如果你到达recurse-left,recurse-right部分,并决定在当前线程数为“低”的情况下为子问题生成线程并进行直接递归,否则你可以组合这些概念。

但是普通的Python并不是这种模式的好语言。 Python线程都运行在相同的解释器硬件线程上,因此您实际上不会获得任何多处理优势。

答案 2 :(得分:0)

Phunctor是正确的,因为“全局解释器锁”阻止多个线程并行执行Python代码,因此线程库并不是并行化此类问题的选择。

但是,在线程库非常有用的情况下,每个线程的代码花费大量时间等待I / O发生。因此,例如,如果您正在实现一个必须命中磁盘或等待网络响应的服务器,那么为每个线程中的请求提供服务可能非常有效,因为线程库可以支持那些不等待I的线程。 / O因此最大限度地使用Python解释器。 (在单个线程中,您必须使用紧密循环检查I / O请求的状态,这会因负载变高而浪费。)