說我有一個寫入文件的函數。我也有一個函數循環重複讀取文件。我有這兩個函數在不同的線程中運行。 (其實我正在通過MDIO讀/寫寄存器,這就是爲什麼我不能同時執行兩個線程,只有一個或另一個線程,但爲了簡單起見,我們只是說它是一個文件)Python:線程+鎖定會顯着減慢我的應用程序的速度
現在當我孤立地運行寫函數,它執行相當快。但是,當我運行線程並讓它在運行之前獲得鎖定時,它似乎運行速度非常慢。這是因爲第二個線程(讀函數)輪詢獲取鎖嗎?有什麼辦法可以解決這個問題嗎?
我目前只是使用一個簡單的RLock,但是我打開任何可以提高性能的改變。
編輯:作爲一個例子,我將舉一個發生了什麼的基本例子。讀線程基本上始終運行,但偶爾會有一個單獨的線程發出調用來加載。如果我通過從cmd提示符運行加載來進行基準測試,則在線程中運行速度至少要慢3倍。
寫線程:
import usbmpC# functions I made which access dll functions for hardware, etc
def load(self, lock):
lock.acquire()
f = open('file.txt','r')
data = f.readlines()
for x in data:
usbmpc.write(x)
lock.release()
讀線程:
import usbmpc
def read(self, lock):
addr = START_ADDR
while True:
lock.acquire()
data = usbmpc.read(addr)
lock.release()
addr += 4
if addr > BUF_SIZE: addr = START_ADDR
在CPython中,除了釋放GIL的C(外部)模塊外,一次只能有一個「運行」的線程,因爲一次只允許一個線程訪問Python引擎。如果MDIO調用沒有釋放GIL,那麼在MDIO調用完成之前,其他函數/ lock *甚至不能啓動*(也就是說,Python代碼不會運行)。 (我不是線程感知的MDIO。) – 2011-03-24 22:56:58
我用一個例子編輯了這篇文章。你是說,一旦寫線程獲得鎖,讀線程永遠不會執行?我在印象之下lock.acquire將輪詢,直到它獲得鎖定?還有什麼可以放慢上述代碼? – 2011-03-24 23:36:26
@Shaunak Amin我沒有試圖說/暗示:-)但CPython線程不能實際運行多個Python線程(它們在內部鎖定在GIL上;只有一些指令允許Python線程「收益「) - 但這並不適用於上述更新,因爲這些鎖是關於usbmpc訪問的。 – 2011-03-25 00:52:28