Python2.7中的多线程

Python2.7中的多线程,python,multithreading,python-2.7,Python,Multithreading,Python 2.7,我不知道如何做多线程,在阅读了一些stackoverflow的答案后,我想到了这个。 注:Python 2.7 from multiprocessing.pool import ThreadPool as Pool pool_size=10 pool=Pool(pool_size) for region, directory_ids in direct_dict.iteritems(): for dir in directory_ids: try:

我不知道如何做多线程,在阅读了一些stackoverflow的答案后,我想到了这个。 注:Python 2.7

from multiprocessing.pool import ThreadPool as Pool
pool_size=10
pool=Pool(pool_size)

for region, directory_ids in direct_dict.iteritems():
    for dir in directory_ids:  
        try:
            async_result=pool.apply_async(describe_with_directory_workspaces, (region, dir, username))
            result=async_result.get()
            code=result[0]      
            content=result[1]
        except Exception as e:
            print "Some error happening"
            print e

        if code==0:
            if content:
                 new_content.append(content)
            else:
                 pass
        else:
            return error_html(environ, start_response, content)
我在这里试图做的是使用不同的区域和目录参数调用
description\u with_directory\u workspace
,并并行运行,以便快速获取新内容中的数据。目前,它是以系列的形式进行的,这给最终用户带来了缓慢的性能


我做得对吗?还是有更好的方法?我如何确认我正在按照预期运行多线程?

您应该了解Python的多处理模块

来自Python:Beazley的基本参考:

Python线程实际上受到了相当大的限制。虽然Python解释器的线程安全性最低,但它使用了一个内部全局解释器锁,只允许一个Python线程在任何给定时刻执行。这将限制Python程序在单个处理器上运行,而不管系统上有多少CPU内核可用

因此:如果有大量CPU处理,请使用多处理

链接到文档:

在您的情况下,多处理池可能很有用

编辑:错过了已使用多处理的代码。请参阅注释,了解可能更有用的答案。另外,有关如何将apply_async与回调一起使用的示例,请参阅: 请注意,池还有一个map\u异步函数

有关上述链接,请参见第16.6.2.9节

EDIT2:在循环外使用get()的示例代码:

from multiprocessing import Pool

def sqr(x):
    return x*x

if __name__ == '__main__':
    po = Pool(processes = 10)
    resultslist = []
    for i in range(1, 10):
        arg = [i]
        result = po.apply_async(sqr, arg)
        resultslist.append(result)

    for res in resultslist:
        print(res.get())

在对所有作业排队之前,您不希望调用
async\u result.get
,否则一次只允许运行一个作业

尝试先将所有作业排队,然后在所有作业排队后处理每个结果。比如:

results = []
for region, directory_ids in direct_dict.iteritems():
    for dir in directory_ids:
        result = pool.apply_async(describe_with_directory_workspaces,
                                  (region, dir, username))
        results.append(result)

for result in results:
    code, content = result.get()
    if code == 0:
        # ...
如果要在异步回调中处理结果,可以向pool.apply\u async提供回调参数,如文档所示:


这段代码展示了Python中多线程的演示。我创建了一个简单的messenger来发送和接收消息

import threading

class Messenger(threading.Thread):
def run(self):
    for _ in range(10):
        print(threading.current_thread().getName())

x = Messenger(name='Send out messages')
y = Messenger(name='Receive Messages')
x.start()
y.start()

我正在使用多处理池,但不确定它是否按照我的预期工作。哎呀,漫长的一天。我看到的一件可能出错的事情是,您正在循环中调用async_result.get()。但是,如果结果不立即可用,get()将被阻止。因此,我有一种感觉,不管怎样,这最终都会按顺序运行。还要注意的是,如果你关心结果返回的顺序(即,你希望它们按调用的顺序返回),那么你可能应该使用映射。这就是重点,我不希望按顺序返回。另外,我还有一些关于“结果”的if-else,所以想一想你们可以建议的任何好的解决方法。如果你们不想让它按顺序进行,就不要做get-in-the循环。在循环之外做。或者使用回调。有没有办法不阻塞地获得结果,而不是对错误进行更多的处理?我的意思是,这可能对我有帮助,但我会寻找更多的选择,这样我就可以称体重了。谢谢:)是的,如果您愿意,您可以提供一个回调例程,以便在每个任务完成时收到通知。使用一个回调例程是否有任何折衷?我能理解的是,它们都做了同样的事情。我想如果你需要做一些处理,关心它们在总体上是如何做的,你会使用前者(收集所有的结果并一次处理它们)。e、 例如,如果其中任何一个失败,是否有更高级别的操作失败?当每一个都是完全独立的事物时,您可以使用后者。就我个人而言,当有干净的替代方法时,我会避免回调(如这里),因为我发现它更容易阅读。我也尝试了回调方法,就像你提到的那样,但似乎不起作用。未调用done_回调。我在这件事上遗漏了什么吗?您尝试的解决方案中可能存在多个问题(代码是串行的,似乎您正在web请求中创建一个新的线程池)。而是从实际问题开始:它是wsgi应用程序的一部分吗(根据
error\uHTML(..)
判断)?
用\..()
函数描述\u做什么(它是IO绑定的)?您是否考虑过在不等待结果完成请求的情况下将任务卸载到后台线程/进程中?
import threading

class Messenger(threading.Thread):
def run(self):
    for _ in range(10):
        print(threading.current_thread().getName())

x = Messenger(name='Send out messages')
y = Messenger(name='Receive Messages')
x.start()
y.start()