多线程使进程变慢

时间:2015-06-19 18:43:32

标签: python multithreading

我有以下任务,我想通过多线程(python3)更快地完成。

import threading, time

q = []

def fill_list():
    global q
    while True:
        q.append(1)
        if len(q) >= 1000000000:
            return

第一个主要不使用多线程:

t1 = time.clock()
fill_list()
tend = time.clock() - t1
print(tend)

结果是145秒的运行时间。

第二个调用两个线程:

t1 = time.clock()
thread1 = threading.Thread(target=fill_list, args=())
thread2 = threading.Thread(target=fill_list, args=())

thread1.start()
thread2.start()

thread1.join()
thread2.join()

tend = time.clock() - t1
print(tend)

这需要152秒才能完成。

最后,我添加了第三个帖子。

t1 = time.clock()
thread1 = threading.Thread(target=fill_list, args=())
thread2 = threading.Thread(target=fill_list, args=())
thread3 = threading.Thread(target=fill_list, args=())

thread1.start()
thread2.start()
thread3.start()

thread1.join()
thread2.join()
thread3.join()

tend = time.clock() - t1
print(tend)

这需要233秒才能完成。

显然,我添加的线程越多,进程所需的时间越长,但我不确定原因。这是对多线程的一个基本误解,还是我的代码中有一个错误,就是多次重复执行任务而不是为同一个任务做出贡献?

1 个答案:

答案 0 :(得分:5)

答案1和2。

首先,您的任务是受CPU限制的,并且在Python进程中,任何给定时间只有一个线程可能正在运行CPU绑定的Python代码(这是由于Global Interpreter Lock:https://wiki.python.org/moin/GlobalInterpreterLock) 。由于切换线程需要花费相当多的CPU(并且你拥有的线程越多,你就越需要支付这笔费用),你的程序不会加速:它会变慢。

其次,无论您使用何种语言,您都要从多个线程修改一个对象(列表)。但为了保证这不会破坏对象,必须同步访问。换句话说,只有一个线程可能在任何给定时间修改它。 Python自动完成(部分归功于前面提到的GIL),但在另一种低级语言(如C ++)中,你必须使用锁定或冒着内存损坏的风险。

跨线程并行化任务的最佳方法是确保线程尽可能隔离。如果他们访问共享对象,那些应该是只读,并且跨线程写入应该尽可能不经常发生,通过线程感知数据结构,如消息队列。

(这就是为什么像Erlang和Clojure这样的高性能并行系统如此高度重视不可变数据结构和消息传递)