Как повторно остановить программу через x минут и снова запустить ее, меняя одну переменную в python? - PullRequest
0 голосов
/ 27 февраля 2019

У меня есть программа, написанная на python, которая выглядит следующим образом:

for i in range(4954):
    ........
    save("/Downloads/pos_" + str(i) + ".h5")

Дело в том, что время работы программы увеличивается в геометрической прогрессии (мы наблюдали это, используя time.time())

Так чтоМне нужно это запустить программу на 10 минут, а затем снова запустить программу.Но мне просто нужно изменить цикл i in for на номер, на котором он остановлен.Я могу сделать работу cron, но что мне нужно сделать, чтобы изменить значение i?

Ответы [ 4 ]

0 голосов
/ 27 февраля 2019

Вот мое решение:

import os
import time
import threading

class test_class(object):
    def __init__(self):
        self.iter_number = 0
        self.new_iter_number = 0

        self.iter_file_dir = "/tmp_file.txt" # tmp file where sto the new iteration number remaining

        self.end_iteration = False # Flag to stop the iteration

        self.delay = 1 # Seconds that means 10 minutes

        with open(self.iter_file_dir, "r") as file:
            self.iter_number = int(file.readline())

        self.run()

    def for_function(self):
        for i in range(self.iter_number):
            save("/Downloads/pos_" + str(i) + ".h5")
            if(self.end_iteration):
                self.new_iter_number = self.iter_number - i
                break

    def run(self):
        threading.Thread(name="Iteration_Thread", target=self.for_function).start()

        time_remaining = self.delay-time.time()%self.delay
        time.sleep(time_remaining)

        self.end_iteration = True

        # Save the file with the new value
        with open(self.iter_file_dir, 'w') as f:
            f.write(str(self.new_iter_number))
test_class()

Идея этого кода проста:

  1. Создайте tmp_file.txt, где вы хотите, и запишите в них количество итерацийчто вам нужно в for.
  2. Создайте таймер, который спит в течение X минут, и после этого установите флаг, который завершает цикл for.
  3. После этого сохраните в tmp_file.txt новый вычисленныйномер итерации

Каждый раз, когда cron запускает программу, он загружает новое значение итерации.Очевидно, что когда итерация завершена в файле, записывается 0, поэтому итерация больше не выполнялась.

0 голосов
/ 27 февраля 2019

Если каждая итерация (каждое значение i) в цикле не зависит друг от друга, вы можете распараллелить ее с ProcessPoolExecutor:

import concurrent.futures

def downloader(i):
    ...
    save("/Downloads/pos_" + str(i) + ".h5")

def main():
    i_range = list(range(4954))
    with concurrent.futures.ProcessPoolExecutor(10) as executor: # create 10 workers (subprocesses)
        for number, result in zip(i_range , executor.map(downloader, i_range)):
            print('File %d is scheduled to download!' % (number))

if __name__ == '__main__':
    main()

Для этого требуется Python3.

0 голосов
/ 27 февраля 2019

Подумайте об использовании генератора:

import time

def gen(n):
    for i in range(n):
        yield n

g = gen(4954)

time_limit = 600

while some_condition:
# whatever condition required for you to continually restart this section

    start = time.time()
    while time.time() - start < time_limit:
        ... some code...
        try: 
            save("/Downloads/pos_" + str(next(g)) + ".h5")
        except StopIteration:
            print('end of iterations')

Где g запомнит итерацию, которую он включил, и продолжит при следующем вызове next(g).

0 голосов
/ 27 февраля 2019

Вы можете использовать marshal.dump (https://docs.python.org/3/library/marshal.html), чтобы сохранить значение при остановке программы, а затем загрузить его с помощью marshal.load при запуске.

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

...