我不熟悉并发编程。在
我想重复执行三个任务。前两个应该一直运行,第三个大约每小时运行一次。前两个任务可以并行运行,但我总是想在第三个任务运行时暂停它们。在
以下是我尝试过的方法:
import threading
import time
flock = threading.Lock()
glock = threading.Lock()
def f():
while True:
with flock:
print 'f'
time.sleep(1)
def g():
while True:
with glock:
print 'g'
time.sleep(1)
def h():
while True:
with flock:
with glock:
print 'h'
time.sleep(5)
threading.Thread(target=f).start()
threading.Thread(target=g).start()
threading.Thread(target=h).start()
我希望这段代码每秒钟输出一个f和一个g,大约每五秒钟打印一个h。但是,当我运行它时,大约需要12个f和12个g才开始看到一些h。看起来前两个线程不断地释放并重新获取它们的锁,而第三个线程则不在循环中。在
注意:在这个简单的例子中,将time.sleep(1)
调用移出with flock/glock块是可行的,但显然不适用于我的实际应用程序,因为线程大部分时间都在执行实际操作。在每次执行循环体之后,当前两个线程睡眠一秒钟时,释放锁,第三个任务仍然无法执行。在
用threading.Events做这个怎么样:
收益率
^{pr2}$(针对注释中的一个问题)此代码尝试测量
h
-线程从其他工作线程获取每个锁所需的时间。在这似乎表明,即使
h
正在等待获取锁,另一个工作线程也可能以相当高的概率释放并重新获取该锁。 没有给h
优先权,因为它等待的时间更长。在davidbeazley在PyCon上介绍了与线程和GIL相关的问题。这是一个pdf of the slides。这是一本引人入胜的读物,可能也有助于解释这一点。在
最简单的方法是使用3个Python进程。如果您在Linux上执行此操作,则每小时进程可以发送一个信号以使其他任务暂停,或者您甚至可以杀死它们,然后在每小时一次的任务完成后重新启动。不需要螺纹。在
但是,如果您决定使用线程,那么尝试在线程之间共享NO数据,只需来回发送消息(也称为数据复制,而不是数据共享)。穿线很难做好。在
但是,多个进程迫使您什么都不共享,因此更容易正确地执行。如果您使用像0MQhttp://www.zeromq.org这样的库来传递消息,那么从线程模型迁移到多进程模型是很容易的。在
使用通信进行同步:
从你的表现来看,它可能不是最佳的,但我发现它更容易遵循。在
输出
^{pr2}$相关问题 更多 >
编程相关推荐