| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Perl: Системное программирование > perl и потоки? |
| Автор: spin2 6.3.2009, 16:40 |
| Нужен совет. Есть такая задача - нужно опрашивать маршрутизаторы (порядка 100 штук) по SNMP и собирать с них определенные переменные (около 15) с интервалом в 5 минут. Поскольку опрашивать нужно достаточно часто, то нужно аккуратно все написать, чтобы не получалось так, что если какой-то маршрутизатор не отвечает, то все сразу зависает надолго. Я так понимаю, что нужно использовать потоки? Я просто с ними не работала до этого, поэтому есть немного вопросов. Сколько потоков можно создавать, чтобы систему не вешать? ОС будет либо Red Hat, либо Solaris. И по какому принципу стоит создавать потоки? На маршрутизаторы или на переменные? Можно, например, создать n потоков, распределять маршрутизаторы между ними и если какой-то маршрутизатор не отвечает, то отправлять роутеры в другие потоки. Или та же логика, но по отношению к переменным. Еще есть такое обстоятельство, что если переменная собирается по маршрутизатору в целом, а не по интерфейсам, то она вся записываться в единый файл для всех роутеров. На чем это лучше писать? На perl, C++ или python? И правильна ли сама мысль о потоках? |
| Автор: NuINu 7.3.2009, 12:12 |
| вот там есть мои примеры как работать с потоками и как работать с задачами, потоки это не единствнный выход(впрочем так же как и задачи) просто в данных абстракциях код относящийся к определенной работе достаточно хорошо изолируется в функции, чего очень тяжело достичь при использовании select/poll, хотя и можно, на перле аналога не помню, но на питоне есть twisted, на перле тоже такой есть. вот смотрите. http://forum.vingrad.ru/forum/topic-247455/kw-%D0%BC%D0%BD%D0%BE%D0%B3%D0%BE%D0%BF%D0%BE%D1%82%D0%BE%D1%87%D0%BD%D0%BE%D1%81%D1%82%D1%8C.html |
| Автор: tolkien 8.3.2009, 21:27 |
| Что хорошего знаете на том и пишите. На перл надо делать через процессы, а не потоки. |
| Автор: spin2 10.3.2009, 15:29 |
| tolkien, процессы - долго и систему жалко. NuINu, спасибо, посмотрю. |
| Автор: ginnie 10.3.2009, 15:56 |
| spin2, я, как обычно, предлагаю сделать при помощи событийной машины на EV. Создаете нужное количество SNMP-запросов и таймер, запускаете событийную машину, затем обрабатываете результаты. Это самый простой вариант, который можно развивать в нужном направлении. |
| Автор: Валерия 11.3.2009, 04:36 |
| tolkien, почему через процессы? Да и могут ли быть shared переменные между процессами? |
| Автор: klem4 11.3.2009, 07:35 | ||
Да, могут. |
| Автор: ginnie 11.3.2009, 12:37 |
А можно пример увидеть? |
| Автор: KSURi 11.3.2009, 14:39 |
| ginnie, shared memory. На CPAN есть реализации. |
| Автор: spin2 11.3.2009, 14:49 |
А можно поподробнее немного? Звучит неплохо. |
| Автор: ginnie 11.3.2009, 15:34 |
| KSURi, сам я shared memory не пользовался, но, судя по описанию, это не совсем "shared переменные". Поэтому я и попросил пример, вдруг есть еще механизмы, о которых я не знаю? |
| Автор: ginnie 11.3.2009, 16:13 |
| spin2, событийная машина позволяет реализовать асинхронную передачу данных для нескольких соединений в рамках одного процесса. Самый быстрый модуль, с которым я имел дело - http://search.cpan.org/~mlehmann/EV-3.53/EV.pm. Суть событийной машины в следующем. Предположим нам надо получить данные от двух серверов. Стандартно это делается так: соединяемся с первым сервером, посылаем запрос, получаем ответ, закрываем соединение, соединяемся со вторым сервером... В случае если соединение установить невозможно, программа будет ожидать до истечения таймаута. Если использовать событийную машину, то алгоритм будет таким: открываем сокет к первому серверу в неблокируемом режиме (не дожидаясь соединения) и создаем функцию-обработчик записи в сокет, открываем сокет ко второму серверу в неблокируемом режиме и создаем функцию-обработчик записи в сокет, создаем таймер для завершения обработки по истечении таймаута (можно задать отдельные таймеры для каждого соединения, по желанию). Запускаем цикл обработки событий. После установления соединения с одним из серверов будет вызвана соответствующая функция-обработчик. Например, для первого сервера. Внутри этой функции мы выполняем запрос к удаленному серверу и создаем функцию-обработчик чтения из сокета, после завершения функции-обработчика записи управление передается обратно в цикл обработки событий (во время выполнения функции-обработчика другие события не обрабатываются, т.к. у нас один поток выполнения). После ответа первого сервера на наш запрос вызывается функция-обработчик для чтения, в которой мы получаем данные из сокета и сохраняем их (или обрабатываем). После получения всех данных закрываем соединение. Функция-обработчик чтения вызывается по мере получения данных от сервера многократно. После получения всех данных от сервера закрываем соденинение. После закрытия всех соединений (или срабатывания таймера) завершаем цикл обработки сообщений. Сама идея событийной машины проста, но при реализации возникают некоторые сложности. В основном они связаны с передачей данных в функции-обработчики (очень часто это делается при помощи замыканий, что делает код непрозрачным С радостью отвечу на конкретные вопросы по теме, если они возникнут. |
| Автор: klem4 11.3.2009, 16:44 | ||||
Ничего нового я вам не скажу Вот простенький примерчик
|
| Автор: ginnie 11.3.2009, 16:50 |
| klem4, насколько я помню, речь шла о разных процессах, а не потоках! |
| Автор: klem4 11.3.2009, 16:53 | ||
|
| Автор: ginnie 11.3.2009, 16:58 |
| klem4, Вы ответили "Да, могут" на вопрос: поэтому я и попросил пример. |
| Автор: klem4 11.3.2009, 17:13 |
| Понятно. На этот вопрос я ответа не знаю. Извиняюсь |
| Автор: arto 12.3.2009, 10:14 |
| всякие IPC::ShareLite или IPC::SharedMem. либо использовать внешние хранилища. |