如何强制执行另一个线程
我有一个主线程,它在做一些比较耗CPU的操作。这个线程在进行计算时必须保持一个锁。
然后还有一些其他线程,它们偶尔需要这个锁,但只需要很短的时间。
我该如何让主线程偶尔允许其他线程执行,而不会因为没有其他线程而减慢自己的速度呢?
定期的
lock.release()
time.sleep(x)
lock.acquire()
对于某个x来说,会把控制权交给其他线程,但如果没有其他线程的话,会让主线程变慢。
另一方面,如果没有调用sleep()
,全局解释器锁(GIL)似乎会在这里造成干扰。因为主线程在执行release()
时持有GIL,所以其他线程显然不能立即从acquire()
返回。因此,主线程继续执行自己的acquire()
方法,而其他线程除非恰好在我释放锁的时候发生GIL的切换,否则永远无法获得锁。
这个问题的正确解决方案是什么?有没有办法强制释放GIL?基本上,我想要一段神奇的代码,确保在下面的测试脚本中,第二个线程总是先获得锁:
import threading
import time
class t1 (threading.Thread):
def run(self):
print "Second thread waiting for lock"
lock.acquire()
print "Second thread got lock"
lock.release()
lock = threading.Lock()
lock.acquire()
t = t1()
t.start()
time.sleep(1)
lock.release()
time.sleep(0) # this works very often, but not all the time
lock.acquire()
print "Main thread got lock"
lock.release()
2 个回答
0
调用 select.select()
并设置超时时间为0,会让全局解释器锁(GIL)暂时释放一下。
4
仅仅释放全局解释器锁(GIL)并不能保证其他线程会有机会运行。
在Unix系统中,你真正想要使用的函数是sched_yield()
。不过在Python的标准库里没有这个函数的接口;如果需要的话,可以通过一个本地模块简单地添加这个功能。
usleep(0)
和select()
有时也可以用来达到类似的目的,但根据不同的系统调度器,效果可能会有所不同。在Windows系统中,你应该使用Sleep(0)。对于这两种情况,可以使用time.sleep(0)。