我正在使用空的while循环,例如: 我有一个在后台运行的线程,它将在5秒内更改一个名为“a”的值。但是,我正在同时使用不同的功能,我想让第二个功能知道值已经改变,所以我一直做的是:
import threading, time
class example:
def __init__(self):
self.a = 0
def valchange(self):
time.sleep(5)
self.a += 1
time.sleep(1)
print("im changing the a value to " + str(self.a))
print("those print commands needs to run after notifier stopped his while and started printing")
def notifier(exam :example, num :int):
while(exam.a != num):
pass
print("it changed to " + str(num))
exa = example()
i = 1
while(i <= 16):
temp= threading.Thread(target=notifier, args=(exa, i, ))
temp.start()
i += 3
i = 1
while(i <= 16):
exa.valchange()
i += 1
值得一提的是,该示例无法使用wait并设置为事件,因为没有迹象表明何时需要运行set,以及后台运行了多少线程,甚至是什么数字将有一个线程等待他们改变。 而且你也不能使用连接,因为改变'a'不是打印的标志,只有条件是标志。 由于最后一个原因,异步和选择也无法帮助我。
有没有办法创造一些东西,这会阻止程序运行直到条件变为真?你可以用你想要的任何编程语言提供你的解决方案,但主要是我使用的是python 3。
编辑:请记住,我需要它来处理每一个条件。我的代码示例 - 只是一个示例,所以如果某些东西在那里工作,它不一定适用于不同的条件。
非常感谢您提前:))
点子:
wait(a == 5) // will do nothing until a == 5
答案 0 :(得分:1)
如果您正在等待某些系统操作完成,则需要使用select
或epoll
系统调用。如果您正在等待某个IO事件,那么您可以使用asyncio
(提供您的Python版本&gt; 3.3),否则您可以考虑twisted
。
如果您正在进行一些CPU绑定操作,则需要考虑多个进程或线程,只有这样您才能有效地进行任何此类监视。让无限循环运行的while循环是一场等待发生的灾难。
答案 1 :(得分:1)
如果您的主题仅在其生命周期结束时更改a
的值一次,那么您可以使用.join()
等待该主题终止。
import threading
import time
class example:
def __init__(self):
self.a = 0
self.temp = threading.Thread(target=self.valchange)
self.temp.start()
self.notifier()
def valchange(self):
time.sleep(5)
self.a = 1
def notifier(self):
self.temp.join()
print("the value of a has changed")
example()
如果线程可能在其生命周期的任何时刻更改a
的值,那么您可以使用threading
模块的一个更通用的控制流对象来协调执行。例如,Event
对象。
import threading
import time
class example:
def __init__(self):
self.a = 0
self.event = threading.Event()
temp = threading.Thread(target=self.valchange)
temp.start()
self.notifier()
def valchange(self):
time.sleep(5)
self.a = 1
self.event.set()
def notifier(self):
self.event.wait()
print("the value of a has changed")
example()
此Event
方法的一个缺点是线程目标必须在set()
更改a
的值时显式调用a
,如果您更改import threading
import time
class example(object):
def __init__(self):
self._a = 0
self._a_event = threading.Event()
temp = threading.Thread(target=self.valchange)
temp.start()
self.notifier()
@property
def a(self):
return self._a
@a.setter
def a(self, value):
self._a = value
self._a_event.set()
def valchange(self):
time.sleep(5)
self.a = 1
def notifier(self):
self._a_event.wait()
print("the value of a has changed")
example()
,这可能会令人恼火你的代码中多次。您可以使用属性自动执行此操作:
valchange
现在a
在设置<asp:Label>
的值后,不必做任何特别的事情。
答案 2 :(得分:0)
您所描述的是自旋锁,根据您的使用情况,可能没问题。
另一种方法是让你等待的代码在达到某个条件时给你回电话。这需要一个异步框架,例如https://docs.python.org/3/library/asyncio-task.html
这些文档中有一些很好的简单示例,所以我不会通过在这里粘贴它们来侮辱你的智慧。