空循环时是否有替换?

时间:2017-11-09 15:07:28

标签: python while-loop conditional-statements wait

我正在使用空的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

3 个答案:

答案 0 :(得分:1)

如果您正在等待某些系统操作完成,则需要使用selectepoll系统调用。如果您正在等待某个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

这些文档中有一些很好的简单示例,所以我不会通过在这里粘贴它们来侮辱你的智慧。