Необходимость взаимного исключения процессов/нитей

Igor Sysoev is at rambler-co.ru
Fri Mar 14 09:44:30 MSK 2008


On Fri, Mar 14, 2008 at 02:40:23AM +0300, Alexander Zheglov wrote:

> 2008/3/13 Igor Sysoev <is at rambler-co.ru>:
> 
> > On Wed, Mar 12, 2008 at 04:26:18PM +0300, Alexander Zheglov wrote:
> >
> > > 2008/3/12 Igor Sysoev <is at rambler-co.ru>:
> > >
> > > > On Wed, Mar 12, 2008 at 04:00:55AM +0300, Alexander Zheglov wrote:
> > > >
> > > > > Добрый день!
> > > > > Написал и использую модуль для ограничения количества запросов к
> > серверу
> > > > за
> > > > > промежуток времени с одного IP. Данные организованы следующим
> > образом: в
> > > > > разделяемой памяти хранятся связанные списки структур статистики по
> > ip
> > > > > адресам, нужная строка выбирается простой хеширующей функцией от ip
> > > > адреса.
> > > > > Соответсвенно там происходит выделение и освобождение памяти. Для
> > защиты
> > > > > указателей списка во время поиска по строке я использую
> > > > pthread_mutex_lock
> > > > > на строку. Чтобы понятнее было:
> > > > > ..
> > > > > addr = ((struct sockaddr_in *)
> > > > (r->connection->sockaddr))->sin_addr.s_addr;
> > > > > key = rlimit_hash_key(addr, ..);
> > > > > ..
> > > > > pthread_mutex_lock(&ctx->hash_locks[key]);
> > > > > ..
> > > > > тут ищем статистику, в общем шаримся по разделяемой памяти
> > > > > ..
> > > > > ret = check_node(..);
> > > > > pthread_mutex_unlock(&ctx->hash_locks[key]);
> > > > > return ret;
> > > > >
> > > > > Обработчик устанавливается через:
> > > > > ..
> > > > > h =
> > ngx_array_push(&cmcf->phases[NGX_HTTP_PREACCESS_PHASE].handlers);
> > > > > ..
> > > > >
> > > > > Собственно вопрос в чем. Я печатаю статистику работы модуля и число
> > > > > процессов в критическом интервале все время равно нулю, несмотря на
> > > > довольно
> > > > > значительную загрузку сервера. У меня складывается ощущение, что я
> > > > чего-то
> > > > > не понимаю.
> > > > > То ли вообще нет необходимости в защите разделяемой памяти в этом
> > месте,
> > > > то
> > > > > ли это специфично только для freeBSD. Под Linux, увы, нет достаточно
> > > > > нагруженного сервера.
> > > > > Собственно вопрос, нужно ли здесь взаимное исключение процессов
> > (нитей)?
> > > > > С уважением, Александр
> > > > > P.S. Если все таки нужно, не имеет ли смысл переделать на, скажем,
> > > > семафоры?
> > > >
> > > > Где находится &ctx->hash_locks[key] ? В разделяемой памяти ?
> > > >
> > > > Я для взаимного исключения процессов использую
> > > > ngx_shmtx_lock()/ngx_shmtx_trylock/ngx_shmtx_unlock(),
> > > > которые для i386/amd64/sparc64/ppc сейчас используют атомарные
> > инструкции
> > > > с уходом в sched_yield().
> > > >
> > > >
> > > Добрый день, Игорь! Да, конечно в разделяемой. За основу я взял Ваш
> > > limit_zone, но некоторые решения для моей задачи мне показались не
> > > эффективными.
> > >
> > > Я старался по максимуму использовать api nginxа, нашел функции
> > > ngx_mutex_lock и тд, но в функции ngx_mutex_init выделение производится
> > > через ngx_alloc, так что я вернулся на стандартное api.
> >
> > Нужно использовать не ngx_mutex_lock, а ngx_shmtx_lock().
> > Он создаётся ngx_shmtx_create.
> >
> > > Алексей Тутубалин мне уже ответил на заданные вопросы, было бы также
> > очень
> > > интересно услышать Ваше мнение. Спасибо.
> >
> > Что показывает ldd nginx, сколько используется воркеров ?
> >
> >
> Посмотрел реализацию. Игорь, дело в том, что для обеспечения возможной
> параллельной обработки запросов я осуществляю лок на строку хеш-таблицы.
> Таких строк - 256. Если используется более одного пула статистики,
> количество пропорционально возрастает. Мне кажется, что 256*количество пулов
> файловых дескрипторов это достаточно серьезное ограничение. Я неправ? Мой
> интерес к задаче связан с тем, что хочется выдержать концепцию нгинкса на
> максимальную производительность, и Ваше мнение здесь очень интересно.

Файловые дескрипторы используются только на платформах, отличных от
i386, amd64, sparc64, ppc.

> ldd nginx? Вы имели ввиду вот это?
> > ldd nginx
> nginx:
>         libcrypt.so.3 => /lib/libcrypt.so.3 (0xa80c2000)
>         libpcre.so.0 => /usr/local/lib/libpcre.so.0 (0xa80da000)
>         libz.so.3 => /lib/libz.so.3 (0xa80f5000)
>         libc.so.6 => /lib/libc.so.6 (0xa8106000)

nginx не слинкован с трэдовой библиотекой и поэтому pthread_mutex_lock() 
это просто заглушка в libc.


-- 
Игорь Сысоев
http://sysoev.ru





More information about the nginx-ru mailing list