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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Thread, передача аргументов 
:(
    Опции темы
Jlekc
Дата 24.1.2006, 18:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



У меня создаеться новый трид (прослушка в клиент-серверном приложении).
При создании трида я передаю указатель на $self:

Код

sub initialized {
    (my $self, my $sock) = @_;
    $self->{"thread"} = threads->create("onReciev", $self);
    ....
}
sub onReciev {
    (my $self) = @_;
    ....
}



но адресс $self-а принятого после запуска трида отличаеться от реального адреса (вообщем дубликат).
Эт конечно мне совсем не подходит. Мне нужно передать указатель что фсе работало синхронно.
Как это зделать?


ЗЫ: К Модераторам: А почему таги code не вставляються?

Это сообщение отредактировал(а) korob2001 - 24.1.2006, 19:20


--------------------
PM MAIL ICQ   Вверх
korob2001
Дата 26.1.2006, 05:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2871
Регистрация: 29.12.2002

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



Что-то я не пойму вопроса. Поясни подробнее, чего ты хочешь добиться?


--------------------
"Время проходит", - привыкли говорить вы по неверному пониманию. 
"Время стоит - проходите вы".
PM MAIL WWW ICQ MSN   Вверх
chaos
Дата 26.1.2006, 09:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Серийный программист
****


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

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



Цитата(Jlekc @ 24.1.2006, 18:31)
У меня создаеться новый трид (прослушка в клиент-серверном приложении).
При создании трида я передаю указатель на $self:

Код

sub initialized {
    (my $self, my $sock) = @_;
    $self->{"thread"} = threads->create("onReciev", $self);
    ....
}
sub onReciev {
    (my $self) = @_;
    ....
}



но адресс $self-а принятого после запуска трида отличаеться от реального адреса (вообщем дубликат).
Эт конечно мне совсем не подходит. Мне нужно передать указатель что фсе работало синхронно.
Как это зделать?


ЗЫ: К Модераторам: А почему таги code не вставляються?

а ты передавай референс(если я тебя конечно правельно понял)
пример
Код

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

my $value;
GetValue(\$value);

========================
sub GetValue {
  my $RefValue = shift;
  $$RetValue = "value";
}


PM WWW   Вверх
Jlekc
Дата 26.1.2006, 11:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



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


--------------------
PM MAIL ICQ   Вверх
korob2001
Дата 26.1.2006, 20:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2871
Регистрация: 29.12.2002

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



А как ты создаёшь потоки?

Вот, для примера, написал программу, которая создаёт 5 потоков ( не путать с процессами ) и ведёт одновременный поиск в пяти текстовых файлах, при этом каждый поток ведёт поиск того, что ему заданно, в часности:
Код

Поток 1: Подсчитывает все вхождения o или O в файле sasser.txt
Поток 2: Подсчитывает все вхождения a или A в файле principles.txt
Поток 3: Подсчитывает все вхождения x или X в файле lanlinux.txt
Поток 4: Подсчитывает общее кол-во символов в файле nixdoc.txt
Поток 5: Подсчитывает общее кол-во целых чисел в файле nixdoc2.txt, число 15.8 будет воспринято 
               как два целых числа 15 и 8. Это не совсем верно, но сейчас не в этом суть. ;)))

Затем потоки собираются в один, после результаты поиска выводятся в STDOUT. Этот пример довольно растянут, но опять же это было сделано намерено, что бы он был более понятен.

Для того, что бы не озадачивать тебя поиском текста для файлов, прицепляю ZIP архив к этому посту. В нём находятся как текстовые файлы с текстом, так и сам исполняемый файл. Всё будет проходить довольно быстро, но если возникнет желание посмотреть на синхронизацию, то раскоментируй строки, которые я закоментировал в подпрограммах: tellLetters(), tellAll(), tellInt().
Код

#!/usr/bin/perl -w
use strict;
use IO::File;
use Thread;

my %threads = ();

# Пять файлов с текстом
my @files = qw( sasser.txt principles.txt lanlinux.txt nixdoc.txt nixdoc2.txt );

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#    Запускаем 5 потоков, каждый из которых будет искать своё в своём файле.   #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
$threads{O}   = Thread->new(\&tellLetters, $files[0], 'O');  # Подсчитывает 'Oo'
$threads{A}   = Thread->new(\&tellLetters, $files[1], 'A');  # Подсчитывает 'Aa'
$threads{X}   = Thread->new(\&tellLetters, $files[2], 'X');  # Подсчитывает 'Xx'
$threads{sim} = Thread->new(\&tellAll, $files[3]);           # Подсчитывает общее кол-во символов
$threads{int} = Thread->new(\&tellInt, $files[4]);           # Подсчитывает общее кол-во целых чисел

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#    Собираем потоки назад и посмотрим результаты поиска.                      #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
print "Total 'O' in file '$files[0]' is: "      . $threads{O}->join()   . "\n";
print "Total 'A' in file '$files[1]' is: "      . $threads{A}->join()   . "\n";
print "Total 'X' in file '$files[2]' is: "      . $threads{X}->join()   . "\n";
print "Total simbols in file '$files[3]' is: "  . $threads{sim}->join() . "\n";
print "Total integers in file '$files[4]' is: " . $threads{int}->join() . "\n";

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#   Подпрограмма будет подсчитывать кол-во заданных букв                       #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
sub tellLetters {
    my $file = shift;
    my $let  = shift;
    my $fh   = IO::File->new($file) or die "Can't open file '$file': $!\n";
    my $c    = 0;
    while (my $line = $fh->getline()) {
           if ( $line =~ s/$let/$c++/egi ) {
                #print "Letter '$let' in file '$file'\n";
                #sleep 1;
           }
    }
    $fh->close();
    return $c;
}

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#   Подпрограмма посчитывает общее кол-во символов                             #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
sub tellAll {
    my $file = shift;
    my $fh   = IO::File->new($file) or die "Can't open file '$file': $!\n";
    my $c    = 0;
    while (my $line = $fh->getline()) {
           $c += length($line);
           #print "Now I tell $c simbols in file '$file'\n";
           #sleep 1;
    }
    $fh->close();
    return $c;
}

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#   Подпрограмма подсчитывает общеекол во цифр в тексте                        #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
sub tellInt {
    my $file = shift;
    my $fh   = IO::File->new($file) or die "Can't open file '$file': $!\n";
    my $c    = 0;
    while ( my $line = $fh->getline() ) {
            if ( $line =~ s/\d+/$c++/eg ) {
                 #print "I find number in file '$file'\n\n";
                 #sleep 1;
            }
    }
    $fh->close();
    return $c;
}

Тебе нужно обратить особое внимание на то, как передаются аргументы в поток, а точене на такие строки:
Код

Thread->new(\&tellLetters, $files[0], 'O'); 

В отдельном потоке запускается подпрограмма tellLetters(), потоку передаём ссылку на неё. Далее через запятую передаём параметры в поток, в данном случае имя файла и искомую строку. Для работы с файлами я использовал модуль IO::File, для того, что бы было проще переписать этот пример для работы с сокетами, так как этот класс является производным от класса IO::Handle, так же как и класс IO::Socket. По нормальному ещё и не мешало бы блокировать потоки, если они используются для записи, с помощью lock().

Насколько я понял задачу, ты хочешь организовать прослушку на сервере, т.е. когда подключается клиет, то для него создаётся отдельный поток, в котором клиент и работает. Основной же поток так и продолжает ожидать нового подключения, если оно будет, то будет создан ещё один поток. Когда клиент отключается, то его поток соединяется обратно с основным потоком?

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

Это сообщение отредактировал(а) korob2001 - 26.1.2006, 22:00

Присоединённый файл ( Кол-во скачиваний: 5 )
Присоединённый файл  teller.zip 14,91 Kb


--------------------
"Время проходит", - привыкли говорить вы по неверному пониманию. 
"Время стоит - проходите вы".
PM MAIL WWW ICQ MSN   Вверх
Jlekc
Дата 27.1.2006, 18:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Догадки твои верны. Но приведенный тобой пример не совсем точен.

Клиент скидуеться на отдельный поток и запускаеться прослушка сообщениый от него.
Пакет присланный клиентом может быть одресован определенному клиенту. Знач должен быть зашареный объект, кторой ведет лист клиентов, и ряд утилитных фукнций.
При создании клиента и вещанья его метода onReciev в отдельном триде на прослушку, как аргумент для создания трида нуна передать указатель на самого себя.
Я передавал референс, но почемуто создавался клон. Воот тут и проблема.

Хтя, быть может это от того что я сижу на Винде. Всеже перл расчитан на юникс.


ЗЫ: Спасибо за помощь но тема исцерпана. Хтя разобраться былоб интересно.
Щас взялся за другую задачу. Этой занимаеться другой чел. Посмотрим как спаравиться.


--------------------
PM MAIL ICQ   Вверх
rcdimon
Дата 27.2.2006, 13:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



У меня есть огромный список URL'ов, с которых нужно скачать страницы... Надо что бы программа качала их в несколько потоков. Какое число потоков оптимально? Например 10 потоков.. Как мне контролировать количество запущенных потоков, что бы их было всегда 10. Когда один отработал- запускался бы новый...

Код

#!/usr/perl58/bin/perl 

use threads;

for ($i=1; $i < 110; $i++){
    @thr[$i] = threads->new(\&haha, $i);
    print @thr[$i]->join();
}
    
    
sub haha {
        my $a = shift;
        return 'hello ' . $a . "\n";
}


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

Например есть у меня массив @urls. В котором может быть большое количество элементов. Каждый элемент- URL адрес. Как мне запускать одну и ту же подпрограмму, что бы в памяти было определенное количество потоков. Каждому новому потоку передавать новый элемент этого массива в качестве параметра. И выполнять работу, пока все элементы массива не будут проработаны.
Добавлено @ 13:53
Кстати подпрограммка, которую я хочу многопоточно запускать довольно немаленькая... использует несколько модулей Perl. А на сервере стоит ограничение- 50 метров ОЗУ на программу....
PM MAIL ICQ   Вверх
rcdimon
Дата 1.3.2006, 11:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Люди! Подскажите smile
PM MAIL ICQ   Вверх
sharq
Дата 1.3.2006, 14:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Perl Liker
**


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

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



rcdimon, к сожалению, я thread'ы на perl не программировал, не приходилось.
Могу рассказать про fork (распараллеливание отлично работает под nix), где-то здесь на форуме приводил функцию, которая скачивает страницы через прокси.

smile
Добавлено @ 14:20
По тредам - perldoc Thread, perldoc threads. smile


--------------------
[color=gray]There's More Than One Way To Do It[/color]
PM MAIL WWW ICQ Skype   Вверх
rcdimon
Дата 1.3.2006, 14:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Отлично. Мне не особо важно как будет происходить распаралеливание. Мне надо что бы просто подпрограмма, в задачу которой как раз входит закачка документов из сети и их обработка, запускалась многопоточно.

покажи пожалуйста пару примеров, или дай ссылку! Мне как я уже говорил надо поддерживать в памяти 10 потоков для обработки большого количества ссылок.

Цитата

распараллеливание отлично работает под nix


А в винде хоть немного работает? Я пишу на винде, но потом будет работать во FreeBSD... Хорошо бы что бы в винде работало хотя бы для разработки
Добавлено @ 14:29
И еще надо что бы не использовалось никаких нестандартных модулей
PM MAIL ICQ   Вверх
sharq
Дата 1.3.2006, 14:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Perl Liker
**


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

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



rcdimon,

Цитата(rcdimon @ 1.3.2006, 15:29 Найти цитируемый пост)
А в винде хоть немного работает? Я пишу на винде, но потом будет работать во FreeBSD... Хорошо бы что бы в винде работало хотя бы для разработки


Цитата(rcdimon @ 1.3.2006, 15:29 Найти цитируемый пост)
покажи пожалуйста пару примеров, или дай ссылку!


perldoc -f fork, perlfork и посмотри особенности использования под Windows (в обще под win32 не работает).

а пример закачки страницы ищи на форуме.

smile

Это сообщение отредактировал(а) sharq - 1.3.2006, 14:36


--------------------
[color=gray]There's More Than One Way To Do It[/color]
PM MAIL WWW ICQ Skype   Вверх
rcdimon
Дата 1.3.2006, 15:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата

а пример закачки страницы ищи на форуме.


Искал- не нашел
PM MAIL ICQ   Вверх
sharq
Дата 1.3.2006, 15:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Perl Liker
**


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

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



rcdimon, плохо ищешь. smile
смотри здесь

smile smile


--------------------
[color=gray]There's More Than One Way To Do It[/color]
PM MAIL WWW ICQ Skype   Вверх
rcdimon
Дата 1.3.2006, 15:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Отлично.. единственное, чего я там не нашел- так это распаралеливание закачек.... а я именно это и просил
PM MAIL ICQ   Вверх
korob2001
Дата 1.3.2006, 23:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2871
Регистрация: 29.12.2002

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



Создай массив с нужным числом потоков.
В примере выше, я сохранял потоки в хеше. Если посмотришь код, думаю создать массив потоков не составит особого труда. Единственное, что нужно добавить это код, который будет контролировать остались ли ещё ссылки в массиве или нет. Если да, то создаёшь поток в том элементе, который только что соединил, если нет, то просто соединяешь поток и ожидаешь завершения работы остальных потоков.
Если я чего-то не понял, поясни подробнее, чего ты хочешь добиться? Ты хочешь создавать зеркала html страниц или же ты хочешь заливать большие файлы в несколько потоков? Как например это делает ReGet Deluxe?

Это сообщение отредактировал(а) korob2001 - 1.3.2006, 23:30


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


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

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


 




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


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

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