LINUX.ORG.RU

Ответ на: комментарий от Skolotovich

Смутно представляю, как.

Исходя из данного метода я делаю на основе примера:

#!/usr/bin/perl -w
use threads;

# В этом массиве будут храниться ссылки на
# созданные нити
my @threads;

# Создаём 3 нити в режиме по прниципу "создал и забыл", тем
# самым позволив открыть  параллельно несколько нитей. Объект
# каждой созданной нити помещается в массив @threads
for my $i (1..3) {
  push @threads, threads->create(\&get_now, $i);
}

# Нити успешно созданы,  ссылки на объекты помещены в массив
# Теперь мы можем для каждого объекта вызвать метод join(),
# заставляющий интерпретатор ожидать завершение работы треда.

foreach my $thread (@threads) {
    # Обратите внимание, что $thread является не объектом, а ссылкой,
    # поэтому управление ему передано не будет.
    $thread->join();
}

sub get_now
{
    my $num = shift;
    print "thread ", $num, " => ", time(), "\n";
    sleep 1;
}

Т.е., при каждом добавлении:

* проходить весь массив @threads, искать завершенные треды (надо ещё узнать, как)

* удалять завершенные

* проверять размер массива, и если там меньше элементов - добавить новый тред, если он заполнен по максимум - подождать секунду и повторить.

Или как?

Chaser_Andrey ★★★★★
() автор топика
Ответ на: комментарий от Chaser_Andrey

по идее ты можешь их ловить обычным wait и делать pthread_join на вернувшийся пид
тогда не надо держать массив, достаточно только счетчик

зы: это если я правильно ман по wait прочитал (:

Skolotovich ★★★
()
Ответ на: комментарий от Skolotovich

Я попытался понять, и гуглил. Но, к сожалению, так и не понял до конца, что и как.

Можешь ткнуть носом в пример?

Chaser_Andrey ★★★★★
() автор топика

Подход неверный.
Верный подход:
Создать сколько нужно тредов и распределять между ними задания. Когда какой-то из тредов закончит работу он возьмет новую пачку заданий. Если заданий не будет то завершится.

Для чего вообще используете треды в перле? I/O?

Olegymous ★★★
()
Ответ на: комментарий от Olegymous

Слушай, это ж гениально! Создать n тредов, в которых будет организован цикл. Каждый тред в каждой итерации цикла будет брать некие данные из предварительно сформированного списка (pop), и если данные закончатся - тред завершается.

Это поразительно просто!

//Треды используются для параллельного запуска нескольких копий системной утилиты ping.

Надеюсь, использование pop в списках в Perl - thread-safe.

Chaser_Andrey ★★★★★
() автор топика
Ответ на: комментарий от Chaser_Andrey

//Треды используются для параллельного запуска нескольких копий системной утилиты ping.

Вдвойне сомнительно использовать для этого треды.
Знакомы с событийными машинами в Perl? Есть модуль AnyEvent::FastPing. Позволит вам пинговать множество хоство в рамках одного процесса параллельно (без создания потоков).

Если всё же хочется использовать утилиту ping. Вы вероятно как-то так хотите её запускать: $response = `ping -c 5 host`. И так в каждом потоке. Это неправильный вариант.
Правильный вариант:
perldoc -f open. Ф-ция open умеет запускать указанную внешнюю программу и устанавливать канал между запущенной программой и вашим процессом. Таким образом вест STDOUT запущенной программы будет доступен через дескриптор файла. Итого: открываем сколько нужно утилит ping и в цикле используя select() чтобы определить дескрипторы доступные для чтения получаем ответы.

Olegymous ★★★
()
Ответ на: комментарий от Olegymous

>AnyEvent::FastPing.

Этот модель довольно специфичен и может не подойдти топикстартеру, но event-ы плюсану

hizel ★★★★★
()
Ответ на: комментарий от Olegymous

Кроме ping необходимо ещё пускать самописную утилиту, тоже параллельно.

Вы вероятно как-то так хотите её запускать: $response = `ping -c 5 host`. И так в каждом потоке. Это неправильный вариант.

А можно узнать, почему? Разве команды не запускаются параллельно в таком случае?

perldoc -f open. Ф-ция open умеет запускать указанную внешнюю программу и устанавливать канал между запущенной программой и вашим процессом. Таким образом вест STDOUT запущенной программы будет доступен через дескриптор файла. Итого: открываем сколько нужно утилит ping и в цикле используя select() чтобы определить дескрипторы доступные для чтения получаем ответы.

Спасибо, я постараюсь разобраться.

Chaser_Andrey ★★★★★
() автор топика
Ответ на: комментарий от Chaser_Andrey

Разве команды не запускаются параллельно в таком случае?

Запускаются параллельно. Но если можно обойтись без потоков, то нужно обходиться без потоков. Потоки в perl достаточно толстые. Почитайте вот: things you need to know before programming Perl ithreads.

Olegymous ★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.