python中的并行性不正常

Moh*_*mis 7 python google-app-engine multithreading python-multithreading python-2.7

我正在使用python 2.7在gae上开发应用程序,ajax调用从API请求一些数据,单个请求可能需要大约200毫秒,但是当我打开两个浏览器并在非常接近的时间发出两个请求时,他们需要的不仅仅是其中两倍,我已经尝试将所有东西都放在线程中,但它不起作用..(这种情况发生在应用程序在线时,而不仅仅是在开发服务器上)

所以我写了这个简单的测试来看看这是否是python中的一个问题(如果忙等待),这里是代码和结果:

def work():
    t = datetime.now()
    print threading.currentThread(), t
    i = 0
    while i < 100000000:
        i+=1
    t2 = datetime.now()
    print threading.currentThread(), t2, t2-t

if __name__ == '__main__': 
    print "single threaded:"
    t1 = threading.Thread(target=work)
    t1.start()
    t1.join()

    print "multi threaded:"
    t1 = threading.Thread(target=work)
    t1.start()
    t2 = threading.Thread(target=work)
    t2.start()
    t1.join()
    t2.join()
Run Code Online (Sandbox Code Playgroud)

结果在mac os x,core i7(4核,8个线程),python2.7:

single threaded:
<Thread(Thread-1, started 4315942912)> 2011-12-06 15:38:07.763146
<Thread(Thread-1, started 4315942912)> 2011-12-06 15:38:13.091614 0:00:05.328468

multi threaded:
<Thread(Thread-2, started 4315942912)> 2011-12-06 15:38:13.091952
<Thread(Thread-3, started 4323282944)> 2011-12-06 15:38:13.102250
<Thread(Thread-3, started 4323282944)> 2011-12-06 15:38:29.221050 0:00:16.118800
<Thread(Thread-2, started 4315942912)> 2011-12-06 15:38:29.237512 0:00:16.145560
Run Code Online (Sandbox Code Playgroud)

这真是令人震惊!! 如果单个线程需要5秒才能完成这个..我认为同时启动两个线程将花费相同的时间来完成这两个任务,但它需要几乎三倍的时间...这使得整个线程的想法无用,如按顺序执行它们会更快!

我在这里想念的是什么..

unu*_*tbu 9

David Beazley在PyCon 2010上发表了关于这个问题的讨论.正如其他人已经说过的那样,对于某些任务,使用特别是多核的线程可能导致性能低于单个线程执行的相同任务.Beazley发现,这个问题与多个具有"GIL战斗"的核心有关:

在此输入图像描述

为避免GIL争用,您可以在单独的进程中运行任务而不是单独的线程,从而获得更好的结果.在模块提供了一个方便的方式来做到这一点特别是因为多处理API是非常相似的线程API.

import multiprocessing as mp
import datetime as dt
def work():
    t = dt.datetime.now()
    print mp.current_process().name, t
    i = 0
    while i < 100000000:
        i+=1
    t2 = dt.datetime.now()
    print mp.current_process().name, t2, t2-t

if __name__ == '__main__': 
    print "single process:"
    t1 = mp.Process(target=work)
    t1.start()
    t1.join()

    print "multi process:"
    t1 = mp.Process(target=work)
    t1.start()
    t2 = mp.Process(target=work)
    t2.start()
    t1.join()
    t2.join()
Run Code Online (Sandbox Code Playgroud)

产量

single process:
Process-1 2011-12-06 12:34:20.611526
Process-1 2011-12-06 12:34:28.494831 0:00:07.883305
multi process:
Process-3 2011-12-06 12:34:28.497895
Process-2 2011-12-06 12:34:28.503433
Process-2 2011-12-06 12:34:36.458354 0:00:07.954921
Process-3 2011-12-06 12:34:36.546656 0:00:08.048761
Run Code Online (Sandbox Code Playgroud)

PS.正如zeekay在评论中所指出的那样,GIL之战对于CPU限制任务来说是非常严重的.它不应该是IO绑定任务的问题.