gpt4 book ai didi

python - 暂停两个 Python 线程,而第三个线程执行某些操作(带锁?)

转载 作者:太空狗 更新时间:2023-10-30 02:34:29 37 4
gpt4 key购买 nike

我是并发编程的新手。

我想重复执行三个任务。前两个应该一直运行,第三个应该每隔一小时左右运行一次。前两个任务可以并行运行,但我总是想在第三个任务运行时暂停它们。

这是我尝试过的框架:

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。看起来前两个线程不断释放并重新获取它们的锁,而第三个线程则被排除在循环之外。

  1. 这是为什么?当第三个线程试图获取当前持有的锁,然后它被释放时,不应该立即获取成功而不是第一个/第二个线程立即再次获取它吗?我可能误会了什么。
  2. 实现我想要的目标的好方法是什么?

注意:将 time.sleep(1) 调用移出 with flock/glock block 适用于这个简单的示例,但显然不适用于线程花费大部分时间的我的实际应用程序做实际操作。当前两个线程在每次执行循环体后休眠一秒钟,并释放锁时,第三个任务仍然不会执行。

最佳答案

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 正在等待获取锁,其他工作线程也可能以相当高的概率释放并重新获取锁。没有给予 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 线程,而第三个线程执行某些操作(带锁?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8103847/

37 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com