zl程序教程

您现在的位置是:首页 >  后端

当前栏目

python实现AutoResetEvent类的阻塞模式方法解析

Python方法模式 实现 解析 阻塞
2023-06-13 09:14:41 时间
搞过C#多线程的人对其中的AutoResetEvent和ManualResetEvent这两个类都理解,其中的WaitOne()方法和Set()以及Reset()方法在线程同步当中用的是比较多的。
AutoResetEvent:当某个线程执行到WaitOne()方法时,该线程则会处于阻塞模式,当被调用了Set()方法,阻塞的线程则会继续向下执行,其状态立即被自动设置为阻塞模式。
ManualResetEvent:当某个线程执行到WaitOne()方法时,该线程则会处于阻塞模式,当被调用了Set()方法,阻塞的线程则会继续向下执行,其状态不会被自动设置为阻塞模式,必须调用其Reset()方法才会将其状态设置为阻塞模式。

在python中threading模块下也有一个类似的线程阻塞模式的类threading.Event(),这个类类似于C#的ManualResetEvent类,在调用set()方法后不能自动变为阻塞模式。有些时候我们在开发项目当中需要这种自动的阻塞模式,我在项目当中也遇到过这种需求,就尝试自己写了个类似的类,吧代码贴出来分享下,代码不多,有不对或者是不合理的地方希望大虾们或者是前辈们能指出,谢谢!
代码如下:
复制代码代码如下:

#encoding:UTF-8
importthreading
classAutoEvent:
def__init__(self):
self.event=None
self.is_wait=False#是否处于阻塞状态
defWait(self,timeout=None):
ifnotself.is_wait:
self.is_wait=True
self.event=threading.Event()#实例化threading.Event()对象
self.event.wait(timeout=timeout)#调用threading.Event().wait()方法,让线程处于阻塞状态
delself.event#释放对象
defSet(self):
ifnotself.is_wait:raise"mustbeinvokeWait()methodbeforeSet()"
self.is_wait=False
self.event.set()#调用threading.Event().set()方法,让线程处于继续

下面是Demo,用来测试的:
复制代码代码如下:

importwx
autoEvent=AutoEvent()#实例化MamualEvent对象
classTestDialog(wx.Dialog):
def__init__(self,parent):
wx.Dialog.__init__(self,parent,-1)
b=wx.Button(self,-1,"print",(50,140))
self.Bind(wx.EVT_BUTTON,self.OnPrint,b)
self.thread=threading.Thread(target=self.work)
self.thread.start()
defwork(self):
whileTrue:
print3
autoEvent.Wait()#阻塞
defOnPrint(self,evt):
autoEvent.Set()#继续
if__name__=="__main__":
app=wx.App()
f=TestDialog(parent=None)
f.Show()
app.MainLoop()

当程序执行时,首先会打印出来个‘3",后面没点击一下print按钮,则会打印一个"3"
测试成功。
注意:如果你将Demo代码中的autoEvent.Wait()和autoEvent.Set()改成threading.Event()类的wait()和set()方法,结果会如下:当程序执行时,会打印个"3",后面点击print按钮后,会一直循环打印"3"