如何强制执行不同的线程

时间:2010-09-25 19:00:52

标签: python

我有一个主线程执行一些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 :(得分:3)

仅发布GIL并不能保证其他线程有机会运行。

在Unix中,您真正想要的电话是sched_yield()。 Python标准库中没有该函数的接口;用原生模块添加一个是直截了当的。

usleep(0)select()有时用于相同的目的,但根据系统调度程序的不同,它并不总是相同的。 Windows,你想睡眠(0)。对这两个使用time.sleep(0)。

答案 1 :(得分:0)

以超时0调用select.select()将暂时释放GIL。