Модераторы: korob2001, ginnie
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Многопоточный обработчик директорий, помогите организовать 
:(
    Опции темы
nIkTo
Дата 18.7.2008, 09:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 218
Регистрация: 5.7.2007

Репутация: нет
Всего: нет



Подскажите как использовать многопоточность для решения такой задачи :
Есть огромное количество директорий, которые необходимо обработать, лежат они в текстовом файле. Необходимо по мере выплнения потоков (~ 50 потоков) читать из файла пути каталогов и выполнять над каталогами операции.
Использование fork с засиранием таблицы процессов не подходит. Тоесть нужно организовать многопоточную работу с файловой системой.
Благодарю за советы.

Это сообщение отредактировал(а) nIkTo - 18.7.2008, 09:03
PM   Вверх
amg
Дата 18.7.2008, 09:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1145
Регистрация: 3.8.2006
Где: Новосибирск

Репутация: 38
Всего: 50



Огромное количество директорий на локальной машине или на удаленных серверах с медленной связью?
PM MAIL   Вверх
nIkTo
Дата 18.7.2008, 11:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 218
Регистрация: 5.7.2007

Репутация: нет
Всего: нет



amg, точное замечание ...
На удаленных серверах с медленной связью
PM   Вверх
FooBar
Дата 18.7.2008, 15:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 58
Регистрация: 25.2.2008

Репутация: 1
Всего: 3



ну вот так например можно с использованием нитей.

Код

#!/usr/bin/perl
use warnings;
use strict;
use threads;
use threads::shared;

open(my $file, '<mmm') || die $!;
my @array : shared = <$file>;
close $file;

threads->new(sub
{
    open(my $f, '>/tmp/'.threads->tid.'.test') || die $!;
    while (1)
    {
        my $string;
        {
           lock @array;
           $string = shift @array || return;
        }
        print $f $string;
    }
}
) for (0..5);

$_->join for threads->list;


PM MAIL   Вверх
IceSunrise
Дата 18.7.2008, 16:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 61
Регистрация: 7.4.2008
Где: Санкт-Петербург

Репутация: 3
Всего: 3



А я все же думаю не стоит использовать треды... К сожалению с перловыми тредами не знаешь где и когда на какие грабли наступишь, хотя здесь вроде все просто. Лучше создавайте контролируемое количество процессов и поддерживайте такой пул.
А если подумать, то зачем здесь большое количество процессов?.... Если я правильно понял, вы читаете файл с директориями на одном сервере, в то время, как сами директории расположены на удаленных сервера и обработка этих директорий осуществляется именно на удаленных серверах. В таком случае достаточно одного процесса, который просто запустит эту самую обработку на всех удаленных машинах. Или я что-то не правильно понял...?
PM MAIL   Вверх
nIkTo
Дата 21.7.2008, 18:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 218
Регистрация: 5.7.2007

Репутация: нет
Всего: нет



FooBar, похоже все выполнилось в одном треде.
Код

[tools@tt temp]$ perl test.pl
[tools@tt temp]$ ls -la
total 24
drwxrwxr-x  2 tools tools 4096 Jul 21 17:48 .
drwx--x--x  9 tools tools 8192 Jul 21 17:47 ..
-rw-rw-r--  1 tools tools  580 Jul 21 17:48 1.txt
-rw-rw-r--  1 tools tools    0 Jul 21 17:48 2.txt
-rw-rw-r--  1 tools tools    0 Jul 21 17:48 3.txt
-rw-rw-r--  1 tools tools    0 Jul 21 17:48 4.txt
-rw-rw-r--  1 tools tools    0 Jul 21 17:48 5.txt
-rw-rw-r--  1 tools tools    0 Jul 21 17:48 6.txt
-rwxrwxr-x  1 tools tools  452 Jul 21 17:47 test.pl
-rw-rw-r--  1 tools tools  580 Jul 21 17:48 dirs.txt

Выполнил это :
Код

#!/usr/bin/perl
use warnings;
use strict;
use threads;
use threads::shared;

open(my $file, '<dirs.txt') || die $!;
my @array : shared = <$file>;
close $file;

threads->new(sub
{
    open(my $f, '>'.threads->tid.'.txt') || die $!;
    while (1)
    {
        my $string;
        {
           lock @array;
           $string = shift @array || return;
        }
        print $f $string;
    }
    close $f;
}
) for (0..5);

$_->join for threads->list;


Это сообщение отредактировал(а) nIkTo - 21.7.2008, 18:48
PM   Вверх
FooBar
Дата 23.7.2008, 00:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 58
Регистрация: 25.2.2008

Репутация: 1
Всего: 3



nIkTo, это из за того что ваш тестовый файл слишком маленький, первый стартоваваший поток все строки обработал, а другим ничего не осталось
PM MAIL   Вверх
nIkTo
Дата 23.7.2008, 14:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 218
Регистрация: 5.7.2007

Репутация: нет
Всего: нет



FooBar, а помоему это из за 
Код

lock @array;

один поток лочит общий массив и до окончания работы с ним не даёт работать другим потокам
PM   Вверх
FooBar
Дата 23.7.2008, 15:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 58
Регистрация: 25.2.2008

Репутация: 1
Всего: 3



Цитата(nIkTo @ 23.7.2008,  14:40)
FooBar, а помоему это из за 
Код

lock @array;

один поток лочит общий массив и до окончания работы с ним не даёт работать другим потокам

массив блокируется только в пределах блока кода, после выхода он разблокируется, просто создайте файл побольше и посмотрите
кстати число в названии созданного файла - это номер потока полученный методом threads->tid

Это сообщение отредактировал(а) FooBar - 23.7.2008, 15:19
PM MAIL   Вверх
Bulat
Дата 23.7.2008, 16:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


татарский Нео
***


Профиль
Группа: Завсегдатай
Сообщений: 1701
Регистрация: 22.3.2006
Где: Альметьевск

Репутация: 5
Всего: 57



Цитата(nIkTo @  18.7.2008,  09:02 Найти цитируемый пост)
Использование fork с засиранием таблицы процессов не подходит. Тоесть нужно организовать многопоточную работу с файловой системой.
Благодарю за советы.

ИМХО, проще делать через fork, при этом контролируя количество дочерних процессов smile


--------------------
менеджер по кодеврайтингу  smile 
PM MAIL WWW   Вверх
nIkTo
Дата 27.7.2008, 22:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 218
Регистрация: 5.7.2007

Репутация: нет
Всего: нет



как сделать вывод результатов каждого потока в один общий файл ?
З.Ы. Так не получилось :
Код

use Fcntl ":flock";
...
open(OUT, ">>result.log");
flock(OUT, LOCK_EX);
print OUT "<...>";
flock(OUT, LOCK_UN);
close(OUT);


Это сообщение отредактировал(а) nIkTo - 27.7.2008, 22:36
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Perl"
korob2001
sharq
  • В этом разделе обсуждаются общие вопросы по языку Perl
  • Если ваш вопрос относится к системному программированию, задавайте его здесь
  • Если ваш вопрос относится к CGI программированию, задавайте его здесь
  • Интерпретатор Perl можно скачать здесь ActiveState, O'REILLY, The source for Perl
  • Справочное руководство "Установка perl-модулей", можно скачать здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Perl: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1598 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.