![](/img/trans.png)
[英]Python socketserver - interaction with threading.Lock()?
[英]interaction of time.sleep with threading.Lock
我试图了解 Python 中的锁并编写了以下示例代码。
import threading
import time
LOCK = threading.Lock()
class Printer(threading.Thread):
def __init__(self, *args, **kwargs):
super(Printer, self).__init__(*args, **kwargs)
self.daemon = True
self.i = 0
def run(self):
while True:
with LOCK:
print(self.i)
self.i += 1
time.sleep(1)
raw_input('press enter to start thread\n')
Printer().start()
raw_input('press enter to pause thread\n')
LOCK.acquire()
raw_input('press enter to resume thread\n')
LOCK.release()
raw_input('press enter to exit program\n')
print('bye!')
这按预期工作并产生 output ,例如:
press enter to start thread
0
press enter to pause thread
1
2
3
4
press enter to resume thread
press enter to exit program
5
6
7
8
bye!
问题
为什么在with
块中缩进time.sleep(1)
会破坏程序?
和
def run(self):
while True:
with LOCK:
print(self.i)
self.i += 1
time.sleep(1)
打印机不能中断!
将您的代码更改为此,看看发生了什么:
import threading
import time
LOCK = threading.Lock()
class Printer(threading.Thread):
def __init__(self, *args, **kwargs):
super(Printer, self).__init__(*args, **kwargs)
self.daemon = True
self.i = 0
def run(self):
while True:
with LOCK:
print(self.i)
self.i += 1
time.sleep(1)
raw_input('press enter to start thread\n')
Printer().start()
raw_input('press enter to pause thread\n')
print('acquiring...')
LOCK.acquire()
print('acquired')
raw_input('press enter to resume thread\n')
LOCK.release()
raw_input('press enter to exit program\n')
print('bye!')
当您的代码尝试运行LOCK.acquire()
时,我认为比赛从with LOCK
和LOCK.acquire()
开始,并且线程大部分时间都赢得了游戏并获得 LOCK 1 秒。 但是在第一种方法中,当 Printer() 等待 1 秒时,主线程获取 LOCK 没有任何问题,因为它是空闲的。 我希望你能明白。 对不起我的语言:))
Hameda169想通了!
我编写了一个带有“on”和“off”按钮的小型演示 GUI,以便将来解释/记住这个概念。
如果您在 LOCK.release() 之后LOCK.release()
time.sleep(0.01)
,则 GUI 按钮在尝试获取锁时可能会冻结很长时间。
它还展示了为什么需要锁。 如果你在on
和off
回调with LOCK
注释掉,你很快就会在按下按钮时得到一个AttributeError
。
# see what happens when there's no sleep AFTER release
# see what happens if on and off functions do not acquire the lock
import Tkinter as tk
import threading
import time
import ttk
class ON(object):
pass
class Printer(threading.Thread):
def __init__(self, *args, **kwargs):
super(Printer, self).__init__()
self.daemon = True
self.on = None
self.i = 0
def run(self):
while True:
LOCK.acquire()
if self.on is not None:
time.sleep(0.1) # make it very likely that self.on can be set to
# None from outside before trying to access
# dummy_attribute -> AttributeError w/o lock!
self.on.dummy_attribute # can error without lock
print(self.i)
self.i += 1
LOCK.release()
time.sleep(0.01) # must sleep after release, else lock can be
# acquired immediately again!
ROOT = tk.Tk()
PRINTER = Printer()
LOCK = threading.Lock()
def on():
with LOCK:
PRINTER.on = ON()
PRINTER.on.dummy_attribute = 'foo'
def off():
with LOCK:
PRINTER.on = None
ttk.Button(ROOT, text='on', command=on).grid()
ttk.Button(ROOT, text='off', command=off).grid()
if __name__ == '__main__':
PRINTER.start()
ROOT.mainloop()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.