Python:线程+锁定大大减慢了我的应用程序

Sha*_*min 5 python multithreading locking

假设我有一个写入文件的函数.我还有一个循环重复读取所述文件的函数.我有这两个函数在不同的线程中运行.(实际上我正在通过MDIO读/写寄存器,这就是为什么我不能同时执行两个线程,只有一个或另一个,但为了简单起见,我们只是说它是一个文件)

现在,当我单独运行write函数时,它执行得相当快.但是,当我运行线程并让它在运行之前获得锁定时,它似乎运行得非常慢.这是因为第二个线程(读取函数)轮询获取锁定?有没有办法解决这个问题?

我目前只使用一个简单的RLock,但我愿意接受任何可以提高性能的变化.

编辑:作为一个例子,我将提供一个基本的例子,说明发生了什么.读线程基本上总是在运行,但偶尔会有一个单独的线程调用加载.如果我通过从cmd提示符运行load来进行基准测试,那么在线程中运行的速度至少要慢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()
Run Code Online (Sandbox Code Playgroud)

读线程:

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
Run Code Online (Sandbox Code Playgroud)

pma*_*v99 4

您在多核机器上使用线程吗?

如果答案是肯定的,那么除非您的 Python 版本为 3.2+,否则在运行线程应用程序时,您的性能将会下降。

David Beazly付出了相当大的努力来找出 GIL 在多核上的情况,并让我们其他人也能轻松理解它。检查他的网站和那里的资源。另外,您可能想看看他在 PyCon 2010 上的演讲。这相当有趣。

长话短说,在 Python 3.2 中,Antoine Pitrou编写了一个新的 GIL,它在单核和多核机器上具有相同的性能。在以前的版本中,拥有的核心/线程越多,性能损失就会增加......

希望能帮助到你 :)

  • 此后,我编写了自己的调度程序来防止线程之间的 GIL 上下文切换,之前需要 10 多分钟的函数现在只需要 20 秒(因为删除了几个竞争周期的线程)。这是一个警告:不要在 PYTHON 2.x 上使用线程!!! (2认同)