Параллельные циклы while в Python



Я довольно новичок в Python и программировании в целом, и я создаю игру в стиле виртуального питомца для моей младшей сестры.



Можно ли запустить 2 , пока циклы параллельны друг другу в python?
например:



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 секунд, но вещи в первом цикле постоянно происходили.



Спасибо за любую помощь

1080   7  

7 ответов:

Взгляните на нарезание резьбы.Таймер .

Здесь есть рецепт кода , чтобы запланировать выполнение функции каждые 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. для новичка, чем правильная координация резьбы.

Как только у вас есть основная логика на месте и работает, затем вы можете рассмотреть потоки снова (с периодическим таймером для того, что вы хотели бы во 2-м цикле в одном потоке, блокирующий вызов buttonbox в главном потоке [[я думаю, что в easygui это должно быть]], оба подавая события в очередь.Очередь [[внутренне потокобезопасно]] с другим потоком, получающим их и работающим соответственно, то есть большую часть того, что вы сейчас имеете в 1-м цикле). Но это довольно сложная архитектурная проблема, поэтому я рекомендую вам не пытаться решать ее прямо сейчас!- )

Для этого вы должны использовать государственные машины (см. Apress pygame book-downloads здесь: 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')

Поместите один из них в функцию, поток.Класс Thread поддерживает целевой атрибут:

import threading
threading.Thread(target=yourFunc).start()

Запустит yourFunc (), работающий в фоновом режиме.

По существу, чтобы обработка происходила параллельно, у вас есть несколько решений

1-отдельные процессы (т. е.: программы), работающие независимо, которые говорят друг с другом через определенный протокол (например: сокеты)

2-или вы можете заставить один процесс порождать несколько потоков

3 - Создайте внутреннюю очередь событий и обработайте их один за другим

Такова общая картина.

Что касается конкретного ответа на ваш вопрос, Вы сказали: "материал в первая петля к б [е] постоянно происходит". Реальность такова, что вы никогда не хотите, чтобы это происходило все время, потому что все, что будет сделано, это использовать 100% процессора, и ничего больше никогда не будет сделано

Самым простым решением, вероятно, является число 3.

Я бы реализовал это так: в моем основном цикле есть поток, который проходит через очередь событий и устанавливает таймер для каждого события. После того, как все таймеры были отправлены основной цикл затем переходит в спящий режим.

Когда таймер истекает, другой затем функция запустит соответствующую функцию для события, которое запустило этот таймер.

В вашем случае, у вас есть два события. Один для отображения меню выбора (первый цикл), а второй для изменения myPotatoHead. Таймер, связанный с первым, я бы установил на 0,5 сек, что делает его больше, уменьшает нагрузку на процессор, но замедляет скорость реагирования, увеличивая его использование больше процессора, для второго события я бы установил 20-секундный таймер.

Конечно, когда таймер истекает, вы бы не делайте while 1, но вы просто пройдете через свое тело цикла while один раз (т. е. избавитесь от while).

Я думаю, что они не могут быть связаны в один цикл while. возможно, вам нужно проверить библиотекуthreading илиmultiprocessing .

Существует также пакет под названиемSimPy , который вы также можете посмотреть. Также могут помочь библиотекиthreading иmultiprocessing .

Comments

    Ничего не найдено.