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

Поиск:

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


Шустрый
*


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

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



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

Выяснил оптимальную схему работы (поправьте если это не так!!!):
Есть основной поток, который принимает коннекты и записывает их в очередь, второй поток берет их из этой очереди последовательно и обрабатывает (взял -> обработал\ответил -> берем следующего).
Набросал:
Код

#!/usr/bin/perl

use HTTP::Daemon;
use LWP::UserAgent;
use Compress::Zlib;
use CGI::Carp qw(fatalsToBrowser);
use threads;
use Thread::Queue;
...
...
my $port = 8080;

$SIG{PIPE} = 'IGNORE';

my $server = HTTP::Daemon->new( LocalPort => $port ) or
die "Can't start server ($@)" unless defined $server;
..
my $ua = LWP::UserAgent->new;

my $data_queue = Thread::Queue->new;   # создаем очередь
threads->create(\&second_thread);             # создаем поток

# Ждем подключения браузера
while (my $conn = $server->accept) {
     $data_queue->enqueue($conn);            #добавляем в очередь - (!!!)тут скрипт слетает(!!!)
}

#обработка запросов
sub second_thread{
  while ( defined( my $conn = $data_queue->dequeue) ){ #берем из очереди
            ...
            #работаем с этим клиентом
            ...
  }
}


Долгими мучениями выяснилось почему происходит вылет при добавлении в очередь. Очередь со строками работает на ура. Но у $conn тип то не такой, а threads::shared не умееть шарить объекты, потому и Thread::Queue этого не умеет.

Так вот, подскажите пожалуйста выход из этой ситуации. Буду очень благодарен. Опыта очень мало - новичОК я.
Или вовсе порекомендуете другой подход?!

ps:
у меня Windows Vista
+ Denwer3_Base_2008-01-13_a2.2.4_p5.2.4_m5.0.45_pma2.6.1
+ Denwer3_Perl_2008-01-13_5.8.8

но рабочий скрипт будет перенесен на FreeBSD

Это сообщение отредактировал(а) ImSave - 5.9.2009, 18:19
PM MAIL   Вверх
ImSave
Дата 6.9.2009, 12:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



может fork ?
тогда как реализовать очередь? или она не нужна..
ну посоветуйте... smile 
PM MAIL   Вверх
sir_nuf_nuf
Дата 6.9.2009, 13:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



apache ?
nginx + fastcgi ?

Зачем вам самому писать web сервер ?


--------------------
user posted image
user posted image
PM MAIL Jabber   Вверх
ImSave
Дата 6.9.2009, 13:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата(sir_nuf_nuf @ 6.9.2009,  13:02)
Зачем вам самому писать web сервер ?

а как тогда реализовать задачу?

на FreeBSD апач

Это сообщение отредактировал(а) ImSave - 6.9.2009, 13:24
PM MAIL   Вверх
sir_nuf_nuf
Дата 6.9.2009, 18:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



под windows тоже есть WWW сервера.


--------------------
user posted image
user posted image
PM MAIL Jabber   Вверх
TDrive
Дата 6.9.2009, 19:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



а зачем делать очередь если это реализовано ОС
функция listen () задаёт количество подключений ожидающих в очереди.
функция accept() берёт по одному подключению из очереди 
после чего можно например через fork() создавать процесс который будет обрабатывать подключение а основной процесс дальше слушает accept().

для примера вот сервер висит на 2000 порту читает строку из клиента и отправляет её обратно клиенту.
для каждого клиента открывается свой процесс а за очередью следит ОС
Код

#!/usr/bin/perl
use Socket;
use IO::Handle;

socket(SERVER, AF_INET, SOCK_STREAM, getprotobyname('tcp'));
setsockopt(SERVER, SOL_SOCKET, SO_REUSADDR, 1);
bind (SERVER, sockaddr_in( 2000, INADDR_ANY));
listen (SERVER,SOMAXCONN);
warn "waiting for incoming connections... \n";
while(1){
    next unless my $remote_addr = accept(SESSION, SERVER);
    warn "Connection \n";
    if(fork==0){
        SESSION->autoflush(1);
        while(<SESSION>){
            chomp($_);
            print SESSION "$_ \n";
        }
        print "Connection finished\n";
        exit 0;
    }
}
close SERVER;





PM MAIL   Вверх
sir_nuf_nuf
Дата 6.9.2009, 22:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



TDrive, вообщем вы правы, но не стоит изобретать велосипед. Лучше имхо использовать готовые решения, если только не нет цели научиться.


TDrive, вы описали классический сервер на форках. Так, например, PostgreSQL работает - на каждое соединение отдельный процесс.
А вы не в курсе как работает апач (в режиме c workerами, а не с потоками) ?
Там процессы живут долго и каждый из них обслуживает более, чем одно соединение.
Т.е. как я понимаю, они fork делают еще до того как делают accept, наследуют слушающий сокет, 
а потом все вызывают accept на нем ? так ?
Или нужны дополнительные блокировки, что бы не конкурировать за него ?


--------------------
user posted image
user posted image
PM MAIL Jabber   Вверх
TDrive
Дата 7.9.2009, 01:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



про апач сказать ничего не могу сам только начал во всём этом разбираться.
PM MAIL   Вверх
ImSave
Дата 7.9.2009, 13:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Спасибо всем, но не могли бы вы по существу мне что-нибудь подсказать...

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

и как сказал уважаемыйsir_nuf_nuf, все это для изучения  smile (просто придумал себе задачу и пытаюсь.....естественно с вашей помощью)
PM MAIL   Вверх
TDrive
Дата 8.9.2009, 00:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



по существу я уже сказал

Цитата(ImSave @  5.9.2009,  12:09 Найти цитируемый пост)
Есть основной поток, который принимает коннекты и записывает их в очередь


коннекты и так ставятся в очередь 
количество очереди устанавливает listen()

кстати случайно наткнулся вот статья очень полезная
http://algolist.manual.ru/web/servers.php
там и про апач есть

если в чём ошибся ссори сам ещё разбираюсь во всём этом.
есть хорошая книга "Линкольн Д. Штайн - Разработка сетевых программ на Perl" советую тем кто интересуется.

пока только этим могу помочь)


PM MAIL   Вверх
ImSave
Дата 8.9.2009, 11:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата(TDrive @ 8.9.2009,  00:50)
пока только этим могу помочь)

Спасибо, почитаем! smile 
PM MAIL   Вверх
ImSave
Дата 11.1.2010, 13:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



с чего начал к тому и хочу вернутся...пробую обойтись без форков.т.к. буду реализовывать очередь с приоритетами
Код

my $server = HTTP::Daemon->new( LocalPort => $port ) or
die "Can't start server ($@)" unless defined $server;

my $ua = LWP::UserAgent->new;
my $data_queue = Thread::Queue->new;   # новая очередь

threads->create(\&second_thread); 

&MainFun($slave) while $slave = $server->accept; #ктото подключился

sub MainFun
{
    my $conn = shift;    
    # записываем в очередь подключившегося (запоминаем его параметры. этих достаточно?)
    $data_queue->enqueue($conn->peerhost().":".$conn->peerport());
    undef $conn;
}

sub second_thread{
  while ( defined( my $client = $data_queue->dequeue) ){ #пока очередь не пуста
     my $cl_host = substr($client, 0, index($client,":"));
     my $cl_port = substr($client, index($client,":")+1);
   # получили параметри клиента
   # тут подскажите как тепер его прослушать
   # нужно что то типа:
   #    $connect->peerhost = $cl_host;
   #    $connect->peerport = $cl_port;
   #    my $request = $connect->get_request; # если активен еще конечно.
  }
}


Это сообщение отредактировал(а) ImSave - 11.1.2010, 13:09
PM MAIL   Вверх
ImSave
Дата 14.1.2010, 19:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



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


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

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


 




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


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

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