2015-02-07 1 views
0

Я экспериментирую с написанием небольшого REST API с Flask. Поскольку я не хочу вводить базу данных на данный момент, я планирую хранить всю информацию, требуемую клиентами в памяти. Прямо сейчас задание cron собирает данные из Интернета, анализирует его и записывает результаты в файл. Задача REST API - предоставить эти данные частично (на основе входящих параметров) клиентам. Вот пример кода, который, по моему мнению будет делать эту работу:Как создать класс, который будет периодически обновлять свои переменные на основе содержимого файла

class DataAnalyzer: 
    TYPE_DAY = 'day' 
    TYPE_WEEK = 'week' 

    def __init__(self): 
     self.__daily_stats__ = [] 
     self.__weekly_stats__ = [] 

    def __load_stats__(self, daily_file, weekly_file, interval): 
     while True: 
      self.__daily_stats__ = [line.strip() for line in open(daily_file, 'r').readlines()] 
      self.__weekly_stats__ = [line.strip() for line in open(weekly_file, 'r').readlines()] 

      time.sleep(interval) 

    def start(self, daily_file, weekly_file, interval): 
     t = threading.Thread(target=self.__load_stats__, args=(daily_file, weekly_file, interval)) 
     t.daemon = True 
     t.start() 

    def get_stats(self, stats_type, skip, count): 
     if stats_type == self.TYPE_WEEK: 
      data_to_filter = self.__weekly_stats__ 
     elif stats_type == self.TYPE_DAY: 
      data_to_filter = self.__daily_stats__ 
     else: 
      raise ValueError("Unknown type of statistics: '" + stats_type + "'") 

     result_list = itertools.islice(data_to_filter, skip, (skip + count)) 

     return list(result_list) 

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

+0

Пожалуйста исправить отступы. – L3viathan

+0

Что будет, когда файл будет изменен во время его чтения? – Jimilian

+0

@Jimilian На самом деле я хотел бы избежать этой ситуации. Возможно ли каким-то образом заблокировать файл? – Zzokk

ответ

0

Не беспокойтесь об этом. GIL поможет вам: Если вы хотите действительно многопоточное приложение, вы должны использовать multiprocessing module.

Глобальный Переводчик Лок (GIL) представляет собой механизм, используемый на компьютерном языке переводчиков для синхронизации выполнения потоков, так что только один поток может выполнять одновременно. Интерпретатор, который использует GIL, будет , всегда позволяющий выполнять только один поток за раз, даже если он работает на многоядерном процессоре .

Ваши потоки будут выполнены один за другим. Не в то же время. Таким образом, ваш data_to_filter будет согласован в любое время. И я думаю, что вы можете изменить

result_list = itertools.islice(data_to_filter, skip, (skip + count)) 
return list(result_list) 

в

return data_to_filter[skip, skip+count] 
+0

Не могли бы вы дать более подробную информацию? Как я вижу, ** load_stats() ** будет вызываться в одном потоке и ** get_stats() ** в другом. Тем не менее, оба они изменяют/получают доступ к ** daily_stats ** и ** weekly_stats **. Как GIL гарантирует, что статистика не будет изменена, а ** get_stats() ** обратится к ней? – Zzokk

+0

Назначение - это атомная операция. Когда 'load_stats()' выполняются, '[...]' генерирует ** новый список **. После этого вы назначаете этот список переменной '_stats_'. Это происходит в одном потоке. В другой теме вы только что сделали копию своей статистики. Операции копирования также являются атомарными. Пока 'get_stats()' работают, другой поток не может работать. – Jimilian

0

Чтобы убедиться, что вы не будете обновлять и получать данные одновременно, вы можете использовать функцию блокировки.

Хорошее объяснение и примеры блокировки с питоном Вы можете найти здесь: http://www.laurentluce.com/posts/python-threads-synchronization-locks-rlocks-semaphores-conditions-events-and-queues/

+0

Автор использует поточный модуль. Поэтому невозможно одновременно обновлять и извлекать данные. Ежедневная и еженедельная статистика разделяются и не синхронизируются. Этот пример не нужен для блокировок. – Jimilian

+0

Это правда, но вопрос в том, как добиться безопасности потоков в целом. – grzgrzgrz3

+0

Как модуль потоковой передачи гарантирует, что данные не будут изменены и обновлены одновременно? – Zzokk

Смежные вопросы