<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=koi8-r">
<TITLE></TITLE>
<META NAME="GENERATOR" CONTENT="OpenOffice.org 2.3 (Linux)">
<META NAME="CREATED" CONTENT="20080123;15515800">
<META NAME="CHANGED" CONTENT="20080123;15525900">
</HEAD>
<BODY LANG="ru-RU" DIR="LTR">
<H2><A NAME="Работаемсразделяемойпамятью"></A>Работаем с разделяемой
памятью<A HREF="http://trakk.pht/spm/vhosting/wiki/Работаем%20с%20разделяемой%20памятью#Работаемсразделяемойпамятью">
¶</A></H2>
<DIV ID="searchable" DIR="LTR">
<P>Начиццо, для работы с ШМ существует такая хрень - как
ngx_shm_zone_t:
</P>
<PRE>struct ngx_shm_zone_s {
void *data; /*Конечная цель мучений - собственно указатель на наши данные в этой зоне. Устанавливается нашим коллбэком.*/
ngx_shm_t shm; /*Шаг номер три.*/
ngx_shm_zone_init_pt init; /*Шаг номер два: коллбэк - инициализирующий зону - предоставляется модулем запросившим её создание.*/
ngx_str_t name; /*Имя - по нему зоны будут различаться менеджилкой зон.*/
void *tag; /*Тут обычно живет адрес структуры модуля использующего зону.
}; *Назначение примерно такое-же - различать.
*Если зона с таким тегом уже есть - при конфигурировании возвращается ошибка,
*а в лог пишется - что такая зона уже используется "для других целей".
*/</PRE><BLOCKQUOTE>
Все зоны живут централизованно в структуре ngx_cycle_t (хоть это-то
он не завязал на хттп). Создание очередной зоны как-правило
происходит при вызове ngx_shared_memory_add() из обработчика
требующей того директивы конфига нашего модуля. Этот вызов добавляет
зону с заданными размером, именем, тегом и конфом (ngx_conf_t) в
список зон. Затем модуль должен навесить свой хэндлер на
ngx_shm_zone_t::init. После обработки конфига, функция инициализации
вызовет коллбэки для всех зон у которых они были заданы функциями
конфигурировавшими модули. Теперь шаг номер три - инициализация
зоны: коллбэк имеет такой вид:
</BLOCKQUOTE>
<PRE STYLE="margin-left: 1cm; margin-right: 1cm">static ngx_int_t ngx_модуль_чего-то-там_init(ngx_shm_zone_t *shm_zone, void *data)
{
ngx_slab_pool_t *shpool;
ngx_модуль_чего-то-там_t *shared_data;
if (data) {
shm_zone->data = data; /*ngx_cycle.c: shm_zone[i].init(&shm_zone[i], oshm_zone[n].data)*/
return NGX_OK;
}
shpool = (ngx_slab_pool_t *) shm_zone->shm.addr;
shared_data = ngx_slab_alloc(shpool, sizeof(ngx_модуль_чего-то-там_t));
if (cache == NULL) {
return NGX_ERROR;
}
/*Ну, тут мы работаем с полученной х..нёй. Всё тупо...*/
...
/*А потом делаем так:*/
shm_zone->data = shared_data;
}</PRE><P>
Вот как-то так...
</P>
<P>Далее в нашем коде можем брать полученный ngx_shm_zone_t *
(который мы храним в main, server, loc или какой ещё конфигурации
нашего модуля), примерно так:
</P>
<PRE>ngx_shm_zone_t *shm_zone;
ngx_slab_pool_t *shpool;
ngz_модуль_main_conf_t *mmcf;
ngz_модуль_чего-то-там *shared_data;
...
shm_zone = mmcf->shm_zone;
shared_data = shm_zone->data;
shpool = (ngx_slab_pool_t *)shm_zone->shm.addr;
ngx_shmtx_lock(shpool->mutex);
shared_data->бла-бла-бла...;
ngx_shmtx_unlock(shpool->mutex);</PRE>
</DIV>
<P><BR><BR>
</P>
</BODY>
</HTML>