[英]Parallel while Loops in Python
我是Python的新手,一般的编程,我正在为我的妹妹创建一个虚拟宠物风格的游戏。
在python中是否可以运行2 while循环? 例如:
while 1:
input_event_1 = gui.buttonbox(
msg = 'Hello, what would you like to do with your Potato Head?',
title = 'Main Screen',
choices = ('Check Stats', 'Feed', 'Exercise', 'Teach', 'Play', 'Go to Doctor', 'Sleep', 'Change Favourite Thing', 'Get New Toy', 'Quit'))
if input_event_1 == 'Check Stats':
myPotatoHead.check_p_h_stats()
elif input_event_1 == 'Feed':
myPotatoHead.feed_potato_head()
elif input_event_1 == 'Exercise':
myPotatoHead.exercise_potato_head()
elif input_event_1 == 'Teach':
myPotatoHead.teach_potato_head(myPotatoHead)
elif input_event_1 == 'Play':
myPotatoHead.play_with_toy()
elif input_event_1 == 'Sleep':
myPotatoHead.put_p_h_asleep()
elif input_event_1 == 'Go to Doctor':
myPotatoHead.doctor_check_up()
elif input_event_1 == 'Change Favourite Thing':
myPotatoHead.change_favourite_thing()
elif input_event_1 == 'Quit':
input_quit = gui.ynbox(
msg = 'Are you sure you want to quit?',
title = 'Confirm quit',
choices = ('Quit', 'Cancel'))
if input_quit == 1:
sys.exit(0)
while 1:
time.sleep(20)
myPotatoHead.hunger = str(float(myPotatoHead.hunger) + 1.0)
myPotatoHead.happiness = str(float(myPotatoHead.happiness) - 1.0)
myPotatoHead.tiredness = str(float(myPotatoHead.tiredness) + 1.0)
如果没有,是否有某种方法可以将其转换为一个循环? 我希望第二个循环中的东西每20秒发生一次,但第一个循环中的东西会不断发生。
谢谢你的帮助
看看Threading.Timer 。
这里有一个代码配方来安排一个每5秒运行一次的函数 。
import thread
import threading
class Operation(threading._Timer):
def __init__(self, *args, **kwargs):
threading._Timer.__init__(self, *args, **kwargs)
self.setDaemon(True)
def run(self):
while True:
self.finished.clear()
self.finished.wait(self.interval)
if not self.finished.isSet():
self.function(*self.args, **self.kwargs)
else:
return
self.finished.set()
class Manager(object):
ops = []
def add_operation(self, operation, interval, args=[], kwargs={}):
op = Operation(interval, operation, args, kwargs)
self.ops.append(op)
thread.start_new_thread(op.run, ())
def stop(self):
for op in self.ops:
op.cancel()
self._event.set()
if __name__ == '__main__':
# Print "Hello World!" every 5 seconds
import time
def hello():
print "Hello World!"
timer = Manager()
timer.add_operation(hello, 5)
while True:
time.sleep(.1)
“并行两个while循环”的唯一方法是将它们放在不同的线程上,但是你需要解决它们之间的同步和协调问题,因为它们到达同一个对象。
我建议你改为在第一个(和单个)循环中进行时间检查,然后按照与时间检查成比例的方式执行第二个循环中的增量; 不是中规中矩,因为buttonbox
调用可能需要很长时间才能返回不确定的量,但更简单的方式来安排,ESP。 对于初学者而言,不是适当的线程协调。
一旦你有了基本的逻辑和工作, 那么你可以再次考虑线程(在一个线程的第二个循环中使用周期性计时器,在主线程中阻塞按钮框调用[[我想在easygui必须是]],将事件送入Queue.Queue [[本质上是线程安全]],另一个线程获取它们并相应地操作,即你现在在第一个循环中拥有的大部分内容)。 但这是一个相当高级的架构问题,这就是为什么我建议你现在不要尝试处理它! - )
您应该使用状态机(请参阅Apress pygame书 - 在此处下载: http : //apress.com/book/downloadfile/3765 ),请参阅第7章。
简化的状态机:
def do_play(pet, time_passed):
pet.happiness += time_pass*4.0
def do_feed(pet, time_passed):
pet.hunger -= time_passed*4.0
def do_sleep(pet, time_passed):
pet.tiredness += time_passed*4.0
if pet.tiredness <= 0:
return 'Waiting'
def do_waiting(pet, time_passed):
pass
def do_howl(pet, time_passed):
print 'Hoooowl'
def do_beg(pet, time_passed):
print "I'm bored!"
def do_dead(pet, time_passed):
print '...'
STATE_TO_FUNC = dict(Waiting=do_waiting,
Sleeping=do_sleep,
Feeding=do_feed,
Playing=do_play,
Howling=do_howl,
Begging=do_beg,
Dead=do_dead
)
class Pet:
def __init__(self):
self.state = 'Waiting'
self.hunger = 1.0
self.tiredness = 1.0
self.happiness = 1.0
def process(self, time_passed):
self.hunger +=1*time_passed
self.tiredness +=1*time_passed
self.happiness -= 1*time_passed
func = STATE_TO_FUNC[self.state]
new_state = func(self, time_passed)
if new_state is not None:
self.set_state(new_state)
if self.hunger >10:
self.set_state('Dead')
elif self.hunger > 5 and not (self.state == 'Feeding'):
self.set_state('Howling')
elif self.tiredness > 5:
self.set_state('Sleeping')
elif self.happiness < 0 and not (self.state == 'Playing'):
self.set_state('Begging')
def set_state(self,state):
if not self.state == 'Dead':
self.state = state
from msvcrt import getch
import time
pet = Pet()
while True:
time0 = time.time()
cmd = getch() # what command?
pet.process(time.time()-time0)
if cmd == 'a':
pet.set_state('Feeding')
if cmd == 's':
pet.set_state('Sleeping')
if cmd == 'd':
pet.set_state('Playing')
将其中一个放入一个函数中,threading.Thread类支持一个target属性:
import threading
threading.Thread(target=yourFunc).start()
将启动yourFunc()在后台运行。
基本上要使处理并行发生,您可以使用多种解决方案
1-独立运行的独立进程(即:程序),通过特定协议(例如:套接字)相互通信
2-或者你可以让一个进程产生多个线程
3-在内部构建事件队列并逐个处理它们
这是一般情况。
至于你问题的具体答案,你说“第一个循环中的东西b [e]不断发生”。 实际情况是你永远不希望这种情况一直发生,因为所有这一切都会占用100%的CPU,而其他任何东西都无法完成
最简单的解决方案可能是3号。
我实现它的方式是在我的主循环中有一个线程,它通过一个事件队列并为每个事件设置一个计时器。 一旦所有定时器都被发送到主循环然后进入休眠状态。
当计时器超时时,另一个函数将为触发该计时器的事件运行相应的函数。
在您的情况下,您有两个事件。 一个用于显示选择菜单(第一个循环),另一个用于更改myPotatoHead。 与第一个相关联的计时器,我将设置为0.5秒,使其更大,降低CPU使用率,但减慢响应速度,增加它使用更多的CPU,对于第二个事件,我将设置20秒计时器。
当计时器到期时,你不会做while 1
但是你只需要通过你的while
循环体一次(即摆脱它)。
我认为他们不能耦合到一个while循环。 也许你需要检查线程或多处理库。
还有一个名为SimPy的软件包,您也可以查看。 线程和多处理库也可能有所帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.