簡體   English   中英

python多線程比串行慢?

[英]python multi-threading slower than serial?

我正在嘗試在python中找出多線程編程。 這是我想要比較串行和並行速度的簡單任務。

import threading
import Queue
import time
import math

def sinFunc(offset, n):
  result = []
  for i in range(n):
    result.append(math.sin(offset + i * i))
  return result

def timeSerial(k, n):
  t1 = time.time()    
  answers = []
  for i in range(k):
    answers.append(sinFunc(i, n))
  t2 = time.time()
  print "Serial time elapsed: %f" % (t2-t1)

class Worker(threading.Thread):

  def __init__(self, queue, name):
    self.__queue = queue
    threading.Thread.__init__(self)
    self.name = name

  def process(self, item):
    offset, n = item
    self.__queue.put(sinFunc(offset, n))
    self.__queue.task_done()
    self.__queue.task_done()

  def run(self):
    while 1:
        item = self.__queue.get()
        if item is None:
            self.__queue.task_done()
            break
        self.process(item)

def timeParallel(k, n, numThreads):
  t1 = time.time()    
  queue = Queue.Queue(0)
  for i in range(k):
    queue.put((i, n))
  for i in range(numThreads):
    queue.put(None)    
  for i in range(numThreads):
    Worker(queue, i).start()
  queue.join()
  t2 = time.time()
  print "Serial time elapsed: %f" % (t2-t1)

if __name__ == '__main__':

  n = 100000
  k = 100
  numThreads = 10

  timeSerial(k, n)
  timeParallel(k, n, numThreads)

#Serial time elapsed: 2.350883
#Serial time elapsed: 2.843030

有人可以向我解釋發生了什么事嗎? 我已經習慣了C ++,使用該模塊的類似版本看到了我們所期望的加速。

其他答案提到了GIL問題是cpython中的問題。 但我覺得有一些遺漏的信息。 在線程中運行的代碼受CPU限制的情況下,這將導致性能問題。 在你的情況下,是的,在線程中做很多計算很可能會導致性能急劇下降。

但是,如果您正在執行更多IO綁定的操作,例如從網絡應用程序中的許多套接字讀取,或者調用子進程,則可以從線程中獲得性能提升。 上面代碼的一個簡單示例是向shell添加一個簡單的簡單調用:

import os

def sinFunc(offset, n):
  result = []
  for i in xrange(n):
    result.append(math.sin(offset + i * i))
  os.system("echo 'could be a database query' >> /dev/null; sleep .1")
  return result

那個調用可能就像等待文件系統一樣真實。 但是你可以看到,在這個例子中,線程將開始證明是有益的,因為當線程在IO上等待並且其他線程將繼續處理時可以釋放GIL。 即便如此,當更多線程開始被創建它們並同步它們的開銷所抵消時,仍然有一個最佳點。

對於CPU綁定代碼,您將使用多處理

來自文章: http//www.informit.com/articles/article.aspx? p = 1850445& seqNum = 9

...線程更適合I / O綁定的應用程序(I / O發布GIL,允許更多的並發)...

關於線程與進程的類似問題參考:
https://stackoverflow.com/a/1227204/496445
https://stackoverflow.com/a/990436/496445

Python有一個嚴重的線程問題。 基本上,將線程添加到Python應用程序幾乎總是無法使其更快,有時會使速度變慢。

這是由於Global Interpreter Lock或GIL。

這是關於它的博客文章 ,其中包括關於該主題的討論。

繞過此限制的一種方法是使用進程而不是線程; 多處理模塊使這變得更容易。

用C編寫的Python庫可以隨意獲取/釋放全局解釋器鎖(GIL)。 那些不使用Python對象的人可以釋放GIL,以便其他線程可以查看,但我相信數學庫一直使用Python對象,因此有效地將math.sin序列化。 由於鎖定/解鎖是一種開銷,因此Python線程比進程慢。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM