说我有一个写入文件的函数。我也有一个函数循环重复读取文件。我有这两个函数在不同的线程中运行。 (其实我正在通过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