3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011

^ 3.3. Процессы в QNX6

В UNIX выделяют последующие типы процессов: системные, бесы и прикладные (пользовательские) [5].

Системные: они являются частью ядра и всегда размещены в оперативки. Они не имеют соответственных им программ в виде исполняемых файлов 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011 и запускаются особенным образом при инициализации ядра системы; выполняемые аннотации и данные этих процессов находятся в ядре системы, таким макаром, они могут вызывать функции и обращаться к данным не легкодоступным для других процессов 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011. Системными процессами UNIX являются: диспетчер свопинга (shed), диспетчер страничного замещения (vhand), диспетчер буферного КЭША (bdfflush), диспетчер памяти ядра (kmademon), к ним относятся процесс init, который является прародителем всех других 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011 процессов ОС и запускающийся при инициализации системы, хотя он не является частью ядра и запускается из исполняемого файла.

Бесы: это неинтерактивные процессы, которые запускаются обыденным образом, оковём загрузки в память соответственных им 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011 программ и производятся в фоновом режиме, они запускаются при инициализации системы и обеспечивают работу разных процессов ОС (система печати, сетевого доступа и т. п.). Они не связаны ни с одним пользовательским сеансом работы 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011 и не могут конкретно управляться юзером. Огромную часть времени они ждут пока тот либо другой процесс не запросит определённую услугу, к примеру, доступ к файловому архиву либо печать документов.

Прикладные процессы: к ним относятся 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011 все другие процессы, выполняющиеся в системе. Эти процессы порождёны в рамках пользовательского сеанса работы. Они могут производиться как в интерактивном так и в фоновом режиме. Но в любом случае время жизни 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011 ограничено сеансом работы юзера. При выходе юзера из системы все его пользовательские процессы будут уничтожены.


В QNX процесс – это выполняющаяся программка. Процесс состоит из вида процесса и метаданных процесса. Образом процесса именуется совокупа 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011 кода (т.е. инструкций для микропроцессора – выполнение этих инструкций и есть выполнение программки) и данных (ими манипулируют при помощи инструкций) [15]. Метаданные процесса – это информация о процессе, которая хранится в структурах данных 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011 ОС и сопровождается ОС. Метаданными являются: информация о физическом размещении кода и данных в оперативки, также атрибуты процесса, к которым относятся:


Процесс всегда содержит 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011 хотя бы один поток. Для процессов начальный код которых подготовлен на языках С/С++, основным потоком процесса является поток, в каком исполняется функция, текстуально описанная под именованием main()[15]. Разглядим программку, которая получает 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011 информацию о значении собственных атрибутов (файл process.c):


#include // вызов стандартной библиотеки

#include // статистическая информация о процессе

int main(int argc, char **argv)

{

struct rusage r_usage; // задается структура последних 4 переметров

printf(“\nProcess 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011 Information:\n); // \n – переход на новейшую строчку

printf(“Process name = \t\t%\n”,argv[0]);

// \t – строчка, argv[0] – выведем нулевой аргумент (процесс)

printf(“User ID = \t\t<%d>\n”,getuid());

// по аналогии вывод остальной инфы

printf(“Effective 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011 User ID = \t\n”,geteuid());

printf(“Group ID = \t\t\n”,getgid());

printf(“Process Group ID = \t\n”,getpgid());

printf(“Process ID (PID) = \t\n”,getpid());

printf(“Parent PID (PPID) = \t 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011\n”,getppid());

printf(“Process priority = \t\n”,getprio());

getrusage(RUSAGE_SELF, &r_usage);

printf(‘\t\n’,r_usage, ru_utime,tv_sec,

r_usage, ru_utime,tv_usec);

printf(‘\t\n’,r_usage 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011, ru_stime,tv_sec,

r_usage, ru_stime,tv_usec);

return EXIT_SUCCESS; // окончание работы программки

}

При помощи директивы #include подключаются две библиотки stdlib.h (стандартная библиотека) и sys/resourses.h (статистическая информация 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011 о процессе). Программка начинает производиться с точки входа   функции main().

Параметрами этой функции являются argc – целое значение количества аргументов командной строчки при запуске программки и argv – массив, в каком находятся значения этих аргументов 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011. Директива struct rusage задает структуру r_usage для получения инфы о статистике выполнения программки. Функция printf() подключаемая через библиотеку stdlib.h обеспечивает вывод на экран сообщений. Управляющий знак \n переводит курсор на 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011 новейшую строчку экрана. Переменная argv[0] всегда содержит имя исполняемой программки. Дальше в функциях printf() происходит вызов функций для получения соответственных атрибутов процесса. Функция getrusage(RUSAGE_SELF, &r_usage) возвращает в структуру 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011 r_usage информацию о статистике выполнения программки. Оператором return программка заканчивается и возвращает в создавший ее процесс сообщение EXIT_SUCCESS (имеет значение 0) – успешное окончание.


Предком всех процессов QNX является админ процессов (процесс 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011 procnto) (рис. 39), идентификатор PID которого равен 1. Другие процессы порождаются в итоге вызова соответственной функции другим процессом, называемым родительским [15].

Первой из функций пораждения процессов является функция fork() – делает дочерний процесс методом «клонирования» родительского процесса. Действие 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011 вызова fork() последующее: порождается дочерний процесс, которому системой присваивается новое уникальное значение PID. Дочерний процесс получает собственные копии файловых дескрипторов, открытых в родительском процессе в точке выполнения fork(). Каждый дескриптор ссылается 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011 на тот же файл, который соответствует аналогичному дескриптору родителя. Блокировки файлов (locks), установленные в родительском процессе, наследуются дочерним процессом. При клонировании родительский и дочерний процессы различаются только идентификаторами PID и PPID. Функцию 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011 fork() рекомендуется использовать исключительно в однопоточных программках.

Разглядим применение функции fork() на примере программки fork.c. Функция fork() возвращает целое число, которое в родительском процессе равно идентификатору PID дочернего процесса 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011, а в дочернем – нулю.

// fork.c

#include

#include

int main(int argc, char **argv, char **env)

// функция возвращает целое значение.

//argc – количство характеристик передаваемых функции аргументов,

//argv – сами аргументы, env – сообщения.

{

pid_t pid 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011; // тип данных для хранения идентификатора процесса

char *prefix;

prefix=(char*)malloc(sizeof(char)); // выделение памяти

pid=fork(); // новый процесс, дочерний к родительскому

if (pid==0) sprintf(prefix, ‘child’); // был ли сотворен дочерний процесс

else sprintf 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011(prefix,”parent’);

printf(“%s Process name =%s\n”,prefix,argv[0]); // вывод инфы

printf(“%s PID=%d\n”,prefix,getpid(0));

printf(“%s PPID=%d\n”,prefix,getppid(0));

return EXIT_SUCCESS; // окончание работы программки

}

На рис.44 показано выполнение программки 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011 fork.c.

Функция vfork() (виртуальный fork()) – употребляется как «облегченная» кандидатура паре вызовов fork()-exec(). В отличии от стандартной функции fork(), она не делает реального копирования данных, а просто перекрывает родительский 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011 процесс, пока дочерний не вызовет exec().



Рис.44. Выполнение программки fork.c.

Семейство функций exec() – подменяют образ вызвавшего процесса обозначенным исполняемым файлом (execl(), execle(), execlp(), execlpe(), execv(), execve(), execvp(), execvpe()). В функциях exec и 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011 spawn употребляются суффиксы: l – перечень аргументов (определяется через перечень данных конкретно в самом вызове); e – перечень аргументов указывается средством определения массива переменных; р – относительный путь, если не указан полный путь к файлу 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011 программки; v – перечень аргументов определяется через указатель на массив аргументов. Функции семейства ехес() заменяют исполняемый код текущего процесса исполняемым кодом из другого файла (не изменяя его идентификатор PID, права доступа 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011, наружные ресурсы процесса, также находящийся в том же адресном пространстве). Потому употребляются эти вызовы конкретно после fork() для подмены копии вызывающего процесса новым.

Программка exec.c иллюстрирует прохождение нового процесса при помощи композиции 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011 вызовов fork() и exec():

#include

#include

int main(int argc, char **argv, char **env)

// функция возвращает целое значение.

// argc – количство характеристик передаваемых функции аргументов,

// argv – сами аргументы, env – сообщения.

{

pid_t pid; // тип 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011 данных

pid=fork(); // итог выполнения функции, определенной ранее,

If (pid==0) //если pid=0, производится фнкция execlp

{ execlp(“process”,”process”, NULL);

// программка заканчивается неудачей

Perror(“Child”);

Exit(EXIT_FAILURE);

}

Waitpid(0,NULL,0);

Printf(“Parants’s PID 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011 =%d\n”,getpid(0));

Printf(“Parants’s PPID =%d\n”,getppid(0));

Return EXIT_SUCCESS;

}

Для пуска программки exec.c из интерпретатора команд sh нужно набрать имя программки exec и надавить кнопку Enter. После чего 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011 интерпретатор команд sh запрашивает админ процессов Procnto о способности сотворения нового процесса exec. Если процесс exec удачно сотворен, то интерпретатор команд sh блокируется до момента окончания процесса exec. Родительский процесс exec делает дочерний 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011 процесс, вызывая функцию fork(). В родительском процессе условие pid==0 не производится, потому что переменная pid равена идентификатору PID дочернего процесса, а он не может быть равен 0. И потом ждет окончания дочернего процесса при 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011 помощи функции waitpid().

В дочернем процессе условие pid==0 производится и при помощи функции execlp(“process”,”process”, NULL) делается попытка загрузить программку process, но путь к ней не указан и функция 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011 execlp возвращает ошибку, которая выводится в поток ошибок функцией perror(“Child”). Потом дочерний процесс заканчивается функцией Exit(EXIT_FAILURE) и возвращает в функцию waitpid() родительского процесса код возврата дочернего процесса. Родительский процесс получает управление 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011, выводит на экран свои идентификаторы PID и PPID и заканчивается оператором return.

На рис.45 показано выполнение программки exec.c.



Рис.45. Выполнение программки exec.c.

Семейство функций spawn() – сходу порождает дочерний 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011 процесс, загрузив обозначенный исполняемый файл (spawn(), spawnl(), spawnle(), spawnlp(), spawnlpe(), spawnp(), spawnv(), spawnve(), spawnvp(), spawnvpe()) [17]. Суффиксы имеют аналогичное значение, что для описанной чуть повыше функции exec(). Это более действенный метод порождения процессов в 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011 QNX Neutrino. Функции семейства spawn () порождают новый процесс с новым идентификатором PID и в новеньком адресном пространстве. В файле spawn.c представлен пример более обычного и резвого метода порождения нового процесса:

// spawn.c

#include 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011

#include

int main(int argc, char **argv, char **env)

{

spawnl(P_WAIT, “process”,”process” ,NULL);

printf(“Parants’s PID =%d\n”,getpid(0));

printf(“Parants’s PPID =%d\n”,getppid(0));

return EXIT 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011_SUCCESS;

}

Самый обычной метод сотворения процесса - запустить из программного кода дочернюю копию командного интерпретатора, которому потом передать команду пуска процесса. Для этого употребляется вызов:

int system(const char * command),

где command - текстовая строчка 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011, содержащая команду, которую подразумевается выполнить ровно в том виде, в каком мы вводим ее командному интерпретатору с консоли.

Процесс заканчивается, если программка делает вызов exit () либо выполнение просто доходит 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011 до точки окончания функции main(), будь то с очевидным указанием оператора return либо без него. Другой путь - посылка процессу снаружи (из другого процесса) сигнала, реакцией на который (предопределенной либо установленной) является окончание процесса 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011.

Разглядим временные издержки на создание процесса при помощи функции fork() на примере программки p2-1.cc [17]:

//p2-1.cc

#include

#include

#include

#include

#include

#include


#include

static double cycle2milisec ( uint64_t ccl ) {

const static double 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011 s2m = 1.E+3;

const static uint64_t cps = SYSPAGE_ENTRY( qtime )->cycles_per_sec;

// частота микропроцессора:

return (double)ccl * s2m / (double)cps;

};


struct mbyte {

#pragma pack( 1 )

uint8_t data[ 1024 * 1024 ];

#pragma pack 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011( 4 )

};


int main( int argc, char *argv[] ) {

mbyte *blk = NULL;

if( argc > 1 && atoi( argv[ 1 ] ) > 0 ) {

blk = new mbyte[ atoi( argv[ 1 ] ) ];

};

uint64_t t = ClockCycles();

pid_t pid = fork();

if( pid == -1 ) { perror( "fork 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011" ); exit( EXIT_FAILURE );}

if( pid == 0 ) exit( EXIT_SUCCESS );

if( pid > 0 ) {

waitpid( pid, NULL, WEXITED );

t = ClockCycles() - t;

};

if( blk != NULL ) delete blk;

cout << "Fork time: " << cycle2milisec( t ) << " msec. [" << t << " cycles]" << endl;

exit( EXIT_SUCCESS 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011 );

};

Программка начинается с точки входа – функции main(). За ранее задается структура mbyte, в какой задается блок данных размером один мб. В основном потоке проверяется условие (argc > 1 && atoi( argv[ 1 ]) > 0 ), где функция atoi 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011() конвертирует символьную сстроку подобающую первому параметру из командной строчки в целое число ( argv[ 0 ] соответствует имени программки – p2-1). Если это значение больше нуля, то при помощи функции new() и структуры mbyte 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011 создается блок данных соответственного размера. Потом при помощи функции ClockCycles() определяется в переменной t имеющей тип данных uint64_t текущее количество процессорных циклов, котрое нужно для определения времни затрачиваемого на создание процесса.

Функция 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011 fork() делает дочерний процесс. Для дочернего процесса pid = 0 потому условие производится и дочерний процесс сразу после проверки условия заканчивается функцией exit( EXIT_SUCCESS ). В это время родительский процесс ждет окончания дочерненого порцесса на функции 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011 waitpid( pid, NULL, WEXITED ). Как дочерний процесс закончится в переменной t = ClockCycles() - t определяется количество процессорных затраченных на порожденние процесса. Потом удаляется блок данных blk и осуществляется вывод на 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011 экран через поток вывода cout и при помощи функции cycle2milisec( t ), модифицирующей процессорные циклы в секунды, время на создание и ликвидирование процесса.

На рис.46 показано выполнение программки p2-1.cc.



Рис.46. Выполнение программки 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011 p2-1.cc.

При запуске программки со значением параметра в Мбайтах от 1 до 100 наблюдается близкая к линенной зависимость времени сотворения процесса от размера его вида в памяти от 17 до 1170 мсек.

Увлекательны не только 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011 лишь издержки на порождение нового процесса, да и то, как «эффективно» сосуществуют параллельные процессы в ОС, как стремительно происходит переключение контекста с 1-го процесса на другой [17]. Для оценки этих издержек разглядим приложение р5.сс 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011.

// P5.cc

#include

#include

#include

#include

#include

#include

int main( int argc, char *argv[] ) {

unsigned long N = 1000;

if( argc > 1 && atoi( argv[ 1 ] ) > 0 ) N = atoi( argv[ 1 ] );

pid_t pid = fork();

if( pid == -1 ) cout << "fork error 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011" << endl, exit( EXIT_FAILURE );

uint64_t t = ClockCycles();

for( unsigned long i = 0; i < N; i++ ) sched_yield();

t = ClockCycles() - t;

delay( 200 );

cout << pid << "\t: cycles - " << t << "; on sched - " << ( t / N ) / 2 << endl 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011;

exit( EXIT_SUCCESS );

};

Программка начинается с точки входа – функции main(). Если при запуске программки в командной строке задано количество повторений цикла, то при помощи функци atoi() оно преобразуется в новое значение переменной 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011 N . Функция fork() делает дочерний процесс. И в дочернем и в родительском процессах (их основных потоках) определяются переменные t (собственных для каждого процесса). Они имеют тип данных uint64_t и хранят 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011 текущее количество процессорных циклов, котрое нужно для определения времни затрачиваемого на переключение контекста процессов.

В каждом из процессов (основных потоках) запускается ^ N раз for-цикл, где производится единственная функция sched_yield(). Она 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011 переводит вызвавший ее процесс (главный поток) из состояния выполнения в состяние готовности к выполнению (хотя квант времени выделенный для работы этого потока еще не истек) и запускает передиспетчеризацию потоков.

После окончания 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011 цила каждый процесс (главный поток) определяет в собственной переменной t = ClockCycles() - t количество процессорных циклов затраченных на выполнение. Делает задержку на 0,2 секунды и выводит на экран через поток вывода cout результаты собственной работы. На рис 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011.47 показано выполнение программки p5.cc в перспективе System Profiler.

Таким макаром, тут применена симметричная схема, где два сразу выполняющихся процесса так симметричны и схожи, что они даже не анализируют PID после 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011 выполнения fork(), они исключительно в наивысшем темпе «перепасовывают» друг дружке активность. Рис. 48 показано взаимодействие 2-ух схожих процессов: вся их «работа» состоит только в том, чтоб как можно резвее передать управление партнеру.



Рис 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011.47. Выполнение программки p5.cc.

Такая работа вероятна при round robin диспетчеризации. На рис. 48 темными стрелками обозначена передача управления от потока к сгустку разных процессов. Итог выполнения программки с разными исходными значениями для микропроцессора 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011 с частотой 533 МГц, указывает, что время передачи управления составляет 0,2 миллисекунды (600 циклов).




Рис. 48. Симметричное взаимодействие потоков


^ Окончание процесса

Окончить процесс можно, направив ему сигнал при помощи утилиты slay либо kill в командной строке 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011, либо из программки при помощи функций: kill(), sigqueue() и др. Окончание процесса производится в две стадии.

На первой – происходит «физическое» ликвидирование процесса, т.е. запираются открытые файлы, освобождается оперативка и т.п 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011. Эта стадия осуществляется потоком-завершителем Админа процессов, выполняющимся от имени уничтожаемого процесса. После этой стадии процесс (главный поток) находится в состояни «зомби». Все потоки процесса   «зомби» находятся в состоянии «DEAD- блокирован».

На 2-ой 3.3. Процессы в QNX6 - Учебное пособие операционные системы ос общего назначения саратов 2011 – уничтожается структура данных о процессе (метаданные), хранящаяся в оперционной системе. Эта стадия производится Админом процессов снутри себя самого.




33-plata-za-uslugi-oao-fsk-ees-doklad-o-prognoze-urovnya-cen-tarifov-na-produkciyu-uslugi-subektov-estestvennih.html
33-pokazaniya-rodstvennikov-storon-5-zakoni-yuridicheskogo-mishleniya.html
33-poryadok-planirovaniya-deyatelnosti-dumi-plan-raboti-dumi-reshenie-saratovskoj-gorodskoj-dumi-ot-27-03-2006.html