暂停两个Python线程,而第三个线程做东西(带锁?)
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了暂停两个Python线程,而第三个线程做东西(带锁?),小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3591字,纯文字阅读大概需要6分钟。
内容图文
![暂停两个Python线程,而第三个线程做东西(带锁?)](/upload/InfoBanner/zyjiaocheng/815/4f5f5245f8a443f0a8c7c242b7a9d20a.jpg)
我是并发编程的新手.
我想反复执行三项任务.前两个应该一直运行,第三个应该每小时运行一次.前两个任务可以并行运行,但我总是希望在第三个任务运行时暂停它们.
这是我尝试过的骨架:
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.然而,当我运行它时,在我开始看到一些h之前需要大约12 f和12 g.它看起来像前两个线程不断释放并重新获取它们的锁,而第三个线程被排除在循环之外.
>为什么?当第三个线程试图获取当前持有的锁,然后它被释放时,不应该立即获取而不是第一个/第二个线程立即再次获取它?我可能误解了一些事情.
>什么是实现我想要的好方法?
注意:移动time.sleep(1)调用with flock / glock块适用于这个简单的例子,但显然不适用于线程花费大部分时间进行实际操作的真实应用程序.当前两个线程在每次执行循环体后休眠一秒钟,并且释放锁定后,第三个任务仍然永远不会被执行.
解决方法:
如何用threading.Events做到这一点:
import threading
import time
import logging
logger=logging.getLogger(__name__)
def f(resume,is_waiting,name):
while True:
if not resume.is_set():
is_waiting.set()
logger.debug('{n} pausing...'.format(n=name))
resume.wait()
is_waiting.clear()
logger.info(name)
time.sleep(1)
def h(resume,waiters):
while True:
logger.debug('halt')
resume.clear()
for i,w in enumerate(waiters):
logger.debug('{i}: wait for worker to pause'.format(i=i))
w.wait()
logger.info('h begin')
time.sleep(2)
logger.info('h end')
logger.debug('resume')
resume.set()
time.sleep(5)
logging.basicConfig(level=logging.DEBUG,
format='[%(asctime)s %(threadName)s] %(message)s',
datefmt='%H:%M:%S')
# set means resume; clear means halt
resume = threading.Event()
resume.set()
waiters=[]
for name in 'fg':
is_waiting=threading.Event()
waiters.append(is_waiting)
threading.Thread(target=f,args=(resume,is_waiting,name)).start()
threading.Thread(target=h,args=(resume,waiters)).start()
产量
[07:28:55 Thread-1] f
[07:28:55 Thread-2] g
[07:28:55 Thread-3] halt
[07:28:55 Thread-3] 0: wait for worker to pause
[07:28:56 Thread-1] f pausing...
[07:28:56 Thread-2] g pausing...
[07:28:56 Thread-3] 1: wait for worker to pause
[07:28:56 Thread-3] h begin
[07:28:58 Thread-3] h end
[07:28:58 Thread-3] resume
[07:28:58 Thread-1] f
[07:28:58 Thread-2] g
[07:28:59 Thread-1] f
[07:28:59 Thread-2] g
[07:29:00 Thread-1] f
[07:29:00 Thread-2] g
[07:29:01 Thread-1] f
[07:29:01 Thread-2] g
[07:29:02 Thread-1] f
[07:29:02 Thread-2] g
[07:29:03 Thread-3] halt
(响应注释中的问题)此代码尝试测量h线程从其他工作线程获取每个锁所需的时间.
它似乎表明,即使h正在等待获取锁,另一个工作者线程也可能以相当高的概率释放并重新获取锁.
因为它等待的时间更长,所以没有给予优先权.
David Beazley在PyCon上介绍了与线程和GIL相关的问题.这是一个pdf of the slides.这是一个迷人的阅读,也可能有助于解释这一点.
import threading
import time
import logging
logger=logging.getLogger(__name__)
def f(lock,n):
while True:
with lock:
logger.info(n)
time.sleep(1)
def h(locks):
while True:
t=time.time()
for n,lock in enumerate(locks):
lock.acquire()
t2=time.time()
logger.info('h acquired {n}: {d}'.format(n=n,d=t2-t))
t=t2
t2=time.time()
logger.info('h {d}'.format(d=t2-t))
t=t2
for lock in locks:
lock.release()
time.sleep(5)
logging.basicConfig(level=logging.DEBUG,
format='[%(asctime)s %(threadName)s] %(message)s',
datefmt='%H:%M:%S')
locks=[]
N=5
for n in range(N):
lock=threading.Lock()
locks.append(lock)
t=threading.Thread(target=f,args=(lock,n))
t.start()
threading.Thread(target=h,args=(locks,)).start()
内容总结
以上是互联网集市为您收集整理的暂停两个Python线程,而第三个线程做东西(带锁?)全部内容,希望文章能够帮你解决暂停两个Python线程,而第三个线程做东西(带锁?)所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。