Twisted ПАиПП — Взгляд изнутри

Проблема

Внутри сервисов возникают задачи обработки множества запросов или\и распараллеливания задач для увеличения быстродействия. На такие вычисления уходит время, причиной может служить следующие ситуации:

  1. Интенсивные вычисления, например вычисление простых чисел. Большой расход ресурсов компьютера и процессорного времени в частности. (Многие сталкивались с такими задачами только в школе)
  2. Ожидании данных необходимых для расчета конечных результатов программы. (Некоторые также сталкивались с такими задачами в школе. Ждали пока за них решат задачу другие.)

Ожидание данных

В рамках сетевого программирования мы часто сталкиваемся с ожиданием данных. Например мы должны отправить письмо:

waiting-schm

Все это кажется не трудоемким, пока у нас одно письмо, а если нам надо разослать спам пользователям Mail.ru =)? Тогда нам лучше распараллелить задачи.

Решить проблему можно воспользовавшись несколькими средствами:

  1. Обрабатывать запросы используя тяжелые процессы(process, fork(вилка)), в этом случае ОС будет запускать один процесс пока другой ждет ответа.
  2. Обрабатывать запросы в потоках(thread), в этом случае системы управления потоками(scheduler) будет запускать поток пока другой ждет ответа.
  3. Использовать не блокирующую систему вызовов — обработать все запросы в рамках одного потока(thread) без блокировки кода во время ожидания данных.

Не блокируемые вызовы

Такой метод использует Twisted. Его реализует Reactor — технология на базе шаблона для взаимоисключения и обработки синхронных событий. Чем то схож с шаблоном проектирования подписчик Observer. Для реализации такой техники в unix подобных системах используются вызовы ядра select и\или poll, epoll (смотрите man select). Такой подход используются в технологиях:

  1. ACE — платформа на базе C++
  2. Medusa — платформа на базе python
  3. MINA java.nio & java.nio.channels
  4. EventMachine - ruby
  5. POE - perl
  6. Twisted

Когда порождается много соединений в одном потоке, управление запросами(scheduling) — задача приложения, а не ОС. Система управления запросами реализована так, что она сама запустит функцию когда необходимое соединение готово для чтения или записи. Такой подход называется асинхронным или событийным программированием.

Примерная модель работы рассылки почты:

  1. Вызываем функцию для соединения с удаленным сервером.
  2. Ответ получаем сразу с пониманием того, что наш механизм сообщит функции отправки почты,когда соединение будет создано.
  3. Когда соединение создано, механизм ядра Twisted вызовет функцию отправки почты.

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

Callbacks

Асинхронная модель для оповещения функции о готовности данных для нее.

deferred-process

Приложение добавляет серию функций к отложенной задаче так, чтобы вызов происходил по мере получение асинхронного результата. Это называется цепочкой callback’ов.

Результат функции в цепочке передается в следующий элемент цепочки, если возникает ошибка, то ее тело передается в errback цепочки. Так мы можем построить логику программу в одной или нескольких независимых цепочках callback’ов, которые могут синхронизироваться с учетом созданных для них правил или работать полностью в асинхронном режиме.

Обобщение

  1. В синхронном программировании функция запрашивает данные и ждет их для дальнейшей обработки.
  2. В асинхронном программировании функция запрашивает данные и просит сообщить ей о их наличии реактор.

Deferred — Объект который позволяет создать цепочку callback’ов и служить сигналом о скором получении данных. Отложенная задача.


Добавить пост в:   Yandex.ru Google Yahoo Bobrdobr.ru Newsland.ru Smi2.ru Rumarkz.ru Memori.ru Myscoop.ru 100zakladok.ru Rucity.com Moemesto.ru News2.ru Delicious Reddit Slashdot Digg Technorati
Комментировать

Поля не обязательны для заполнения, по умолчанию комментарий от Anonymous

captcha
Оставить комментарий используя OpenID

Пожалуйста выберите сервер с вашим аккаунтом:

Комментарии

antisvin 26.08.2008 14:26

Выделять потоки и процессы в отдельные группы не совсем корректно, т.к. они отличаются только наличием общей памяти, что в данном случае не существенно, ведь речь идет не о ней а о блокирующем или нет вводе-выводе. Поэтому планировщики процессов у многих ОС не дифференцирует их.

Кроме того, есть несколько подходов позволяющие обьеденить потоки и события. Модель актеров (реализована в erlang, scala и менее известных языках) существующая аж с 1973 года, которая представляет вычисления как множество процессов без общей памяти асинхронно обменивающихся сообщениями. При этом, например, erlang может использовать потоки ОС для реализации собственных в виде m:n, т.е. тысячи (или миллионы, хотя это скорее из области бенчмарков а не реального применения) своих легковесных потоков распределять между несколькими потоками ОС чтобы загрузить все процессоры.

Ещё попадалась интересная работа на хаскеле, где автор сделал либу которая преобразовывала код написанный в блокирующем стиле для асинхронного исполнения. Соответственно, писать и отлаживать код проще, но при этом мы имеем высокую производительность от event-based кода. Примечательно что у него часто твистед упомянался в диссертации, которую очень рекоммендую почитать.

Ммм… Спасибо, ты как всегда прав, но сильно углубился в подробности. Понятно что путать потоки, процессы и не блокируемый ввод-вывод нелепо. Дело в том, что в оригинальной документации Twisted используется такое разделения для первоначального упрощения понимания прикладной области.

В реальных же проектах конечно используется симбиоз инструментария для того чтобы с максимальной пользой и минимальными затратами загружать CPU. Мне конечно интереснее пообщаться и углубиться в гетерогенные и нейронные сети, протоколы связи между нодами, но я стараюсь с максимальной пользой использовать информацию которая у меня уже есть, чтобы она не ушла без следа и принесла кому-то пользу, дала почву для размышлений.

Твои комментарии жду с нетерпением, уже читаю доки. Открывается темная сторона “Hello world” от инфернального Антисвина =).

Пыс. Пыс. На бабье лето в Питер собираюсь, может пересечемся ;)