Студопедия

Главная страница Случайная страница

Разделы сайта

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Основы программирования обслуживания вызовов в реальном времени






В наше время нельзя описывать станции автоматической комму­тации, не уделяя основного внимания их программному обеспече­нию - самой сложной (и самой трудоемкой при разработке) части цифровой АТС. Эта сложность обусловлена двумя рассматриваемы­ми в данной главе составляющими: функциональное наполнение ПО и выполнение задач в реальном времени. Кроме того, в следующей главе 10 мы поговорим о ПО технического обслуживания и админи­стративного управления, а в главе 11 - о ПО телекоммуникационных услуг.

Для лучшего восприятия излагаемого в этом параграфе материа­ла полезно с самого начала привести следующие цифры. Станцион­ному ПО АТС, обслуживающей 10000 абонентов, необходимо одно­временно держать под контролем приблизительно 1000 соедине­ний в фазе разговора плюс 200 соединений в фазе установления/ разрушения плюс 20 транзакций эксплуатационного управления, причем требования реального времени ограничивают время отклика программного обеспечения для обработки сигнализации интер­валом 10-100 мс, для функций обработки вызова - интервалом 100-1000 мс, для диалога человек-машина - 1-3 с, для транзакций тех­нической эксплуатации - 1-10 с.

В новых цифровых АТС, например, 5 ESS компании Lucent, DMS-100 компании Nortel, EWSD компании Siemens и др. функционирование ПО в реальном времени отчасти скрыто за их операционными систе­мами, что хотя и упрощает разработку программ для этих систем, но и затемняет реальное понимание работы систем. В ранних системах коммутации с монолитной программной архитектурой, подобной ар­хитектуре 1 ESS или ИВТУ, поведение программного управления в ре­альном времени более очевидно. И хотя среда, в которой специали­сты должны были разрабатывать ПО первых АТС с управлением по записанной программе, была весьма сложной и не очень комфорт­ной, педагогические возможности объяснить поведение ПО этих АТС в реальном времени намного лучше.

Например, уже рассматривавшийся в главе 6 проект программ­ного управления коммутационной станцией с помощью специали­зированной электронной управляющей машины «Нева» предусмат­ривал разработку программ для этого компьютера на языке Ассемб­лера, используя косвенную адресацию, макрокоманды и подпро­граммы. Язык высокого уровня не применялся, т.к. хотя Алгол, Ко­бол и Фортран уже были изобретены, их использование для задач реального времени в системе управления узлом коммутации, да еще на таких «тихоходных» компьютерах, было попросту невозможно. Система команд «Невы» содержала, кроме универсальных команд (сложение, вычитание, логические операции, сдвиги ит.п.), большое количество специализированных команд, обеспечивавших выигрыш времени в процессе обработки вызовов или экономию памяти ма­шины. Так, в группе команд арифметических операций к четырем обычным командам были добавлены часто использовавшиеся коман­ды сложения кода с единицей и вычитание из кода единицы. Логи­ческие операции включали в себя логический сдвиг влево и вправо (ЛСД); циклический сдвиг (ЦСЖ); размножение операционного ре­гистра (РМ). Была введена специальная группа операций побито­вой обработки информации, содержавшая восемь (а с учетом мо­дификаций - 18) разных по смыслу команд: единица в разряде (РЕ); нуль в разряде (РН); инверсия разряда (РИ); проверка разряда (РП); номер левой единицы (НЕ); номер левой единицы с инверсией (НЕЙ); номер несовпадений в массиве (ННМ) и номер несовпадений с ин­версией в массиве (ННИМ).

Можно представить, как непривычно это выглядит сейчас, но для тогдашних программистов, к которым принадлежал и автор этих строк, латинский алфавит ограничивался практически шестью бук­вами А, В, С, D, E, F, необходимыми для шестнадцатеричной системы счисления, а мнемоника ассемблерных команд вполне привычно сочеталась с кириллицей.

К этим ассемблерным командам относились также операции ас­социативного поиска, содержавшие две команды поиска в упорядо­ченном и в неупорядоченном массивах. Операции с циклическими массивами и команды системы прерывания ('возбудить сигнал пре­рывания', 'гасить сигнал', 'маскировать сигнал', 'демаскировать сигнал', 'есть прерывание', 'нет прерывания' и 'конец программы') как раз и обеспечивали специфику обслуживания вызовов в реаль­ном времени.

Для управляемого ЭУМ «Нева» импульсно-временного транзит­ного узла ИВТУ, также рассмотренного в главе 6, был выбран единый цикл сканирования всех комплектов, равный 10 мс. Результаты сканирования использовались для формирования очередей к про­граммам обработки вызовов. При этом смысловое содержание вво­димой из периферийных управляющих устройств (ПУУ) информации определялось по таблицам решений, которые составлялись для всех типов АТС, связанных с ИВТУ, и в которых учитывались способ пере­дачи сигналов, скорость этой передачи и ряд других факторов. Про­блемы реального времени обусловили разработку специализирован­ной телефонной операционной системы (ТОС), основной частью ко­торой являлась подсистема приоритетного обслуживания, опреде­лявшая последовательность вызова программ, к которым в данный момент имеются запросы. Все программы были распределены по абсолютным и относительным уровням приоритета. При этом про­граммы сканирования и ввода вызывались на нулевом (высшем) уровне приоритета по расписанию, т.е. через заданные интервалы времени. Система приоритетного обслуживания проектировалась таким образом, чтобы, с одной стороны, обеспечить необходимую последовательность выполнения отдельных программ и, с другой, -сократить до минимума затраты времени на переключение про­грамм, а вместе с тем и минимизировать объем памяти, необходи­мой для хранения отложенных программ.

Система прерывания содержала поле для запоминания сигналов прерывания, делившихся на 17 абсолютных приоритетных уровней, из которых наивысшим приоритетным уровнем обладал единствен­ный аппаратный уровень; остальные 16 были программными. На ка­ждом из абсолютных приоритетных уровней было предусмотрено до 256 относительных приоритетов, которые не вызывали прерывания текущих программ, но определяли порядок обслуживания программ данного уровня. Для определения оптимального числа уровней пре­рывания, распределения всех программ по абсолютным и относи­тельным приоритетным уровням, определения размеров цикличе­ских массивов очередей заявок и решения других задач телефон­ной операционной системы последняя должна была быть тщательно рассчитана и оптимизирована, так как от этого зависела правиль­ность распределения ресурсов управляющего компьютера и, в пер­вую очередь, использование ресурса времени центрального процес­сора. Оптимизация телефонной операционной системы производи­лась с помощью разработанных автором математического аппара­та и инженерных методов расчета и оптимизации приоритетного обслуживания программ [47].

Концептуально иные подходы к решению тех же задач програм­мирования в реальном времени были разработаны для архитектуры программного обеспечения 1ESS. Время выполнения программ в процессоре 1 ESS распределяется между классами программ, ко­торые отвечают за ввод/вывод с запуском от таймера, обработку вы­зовов и техническое обслуживание системы. Распределение време­ни процессора между этими тремя классами программ весьма под­робно рассмотрено в книге Р.Томпсона [200]. Там указано, что ска­нирование свободных абонентских линий в 1ESS производится каж­дые 100 мс, и что такая частота вызовов соответствует, в среднем, одному новому вызову во временном интервале опроса при интен­сивности потока вызовов, составляющей 36000 вызовов в ЧНН. Если бы эти вызовы были распределены во времени строго равномерно (что невероятно), распределение рабочего времени процессора между тремя классами программ в интервале, равном 1 минуте, было бы гладким, равномерным и неизменным. В реальных условиях по­ток вызовов имеет случайный характер, а распределение рабочего времени процессора определяет усредненная величина - интенсив­ность нагрузки.

На рис. 9.2 показано, как распределяется между тремя классами программ рабочее время процессора в зависимости от интенсив­ности телефонной нагрузки в системе. На оси у показано рабочее время процессора, а на оси х- интенсивность телефонной нагрузки в системе. В левой стороне рис. 9.2 состояние системы соответст­вует 3 часам ночи, когда телефонная нагрузка практически равна 0. В правой стороне рисунка состояние системы соответствует часам наибольшей нагрузки, когда процессор с ней едва справляется. Циф­ры на рис. 9.2 условны, для простоты предполагается, что распре­деление рабочего времени процессора является линейной функци­ей интенсивности нагрузки.

Программы опроса спланированы на выполнение с постоянной частотой. Но исполнение программы, которая ищет и находит заяв­ку, занимает больше рабочего времени процессора, чем исполне­ние той же программы, когда она ищет заявку и не находит ее. Пред­положим, что программы опроса расходуют 40% рабочего времени процессора именно на вспомогательные действия, связанные с по­иском заявок - сканирование датчиков состояния снятия трубки, изменений во внутренних буферах контроля, сигналов от таймера и пр. В левой части рис. 9.2, которая соответствует нулевой теле­фонной нагрузке и отсутствию заявок, общее рабочее время про­цессора складывается только из времени опроса. Предположим, что программы опроса расходуют на каждое исполнение, в среднем, на 50% больше рабочего времени процессора при телефонной нагруз­ке Ттах, чем наихже исполнение при телефонной нагрузке 0. В таком случае рабочее время процессора, выделяемое программам опро­са, в правой части рис. 9.2 возрастает до 60%.

Рис. 9.2 Распределение рабочего времени управляющего процессора при разной интенсивности телефонной нагрузки на примере 1 ESS

Расходование 40-60% рабочего времени только на поиск заявок может показаться неэффективным. Но лучшим показателем эффек­тивности служит рабочее время процессора, затрачиваемое на об­служивание найденной заявки. Пусть п -среднее число заявок, най­денных программами опроса в типовом 5-миллисекундном интер­вале времени. Если нагрузка мала, программы опроса расходуют 2 миллисекунды (40%) из 5 миллисекунд интервала и, возможно, на-ходяттолько п=1 заявку. На одну найденную заявку расходуется 2 мс. Если нагрузка большая, программы опроса расходуют 3 мс (60%) из 5 миллисекунд интервала, но могут найти и п=60 заявок. На одну най­денную заявку, в среднем, израсходуется 0.05 мс. В том случае, ко­гда ввод/вывод запускается прерыванием, и на каждое прерывание расходуется дополнительно 0.1 мс рабочего времени, одна задача расходует 0.1 мс, а 60 задач расходуют 6 мс. Таким образом, ввод/ вывод с запуском от прерывания может быть в 20 раз эффективней ввода/вывода с запуском от таймера при малой телефонной нагруз­ке, но при высокой телефонной нагрузке он вдвое менее эффекти­вен. Поскольку архитектуру определяет ситуация с высокой интен­сивностью телефонной нагрузки - эффективность важна только для загруженной системы программного управления, а когда интенсив­ность телефонной нагрузки невысока - рабочее время управляющего процессора экономить незачем, потому что у процессора все равно немного работы.

Предположим, что программы обработки вызовов, регулярно выполняемые вне зависимости от наличия или отсутствия телефон­ной нагрузки, расходуют 10% рабочего времени процессора, а сама обработка вызовов занимает дополнительно 30% рабочего време­ни процессора, что соответствует точке Ттах. В левой части рис. 9.2, где интенсивность телефонной нагрузки равна 0, и обрабатываемых вызовов нет, общее рабочее время процессора, выделяемое для обработки вызовов, составляет только 10% рабочего времени, за­нимаемого регулярными программами. В правой части рис. 9.2, где интенсивность телефонной нагрузки равна Ттах, обработка вызовов занимает 40% рабочего времени процессора.

Заметим, что при интенсивности телефонной нагрузки Ттах опрос и обработка вызовов вместе занимают 100% рабочего времени про­цессора. Поскольку свободного рабочего времени не остается, ин­тенсивность телефонной нагрузки Ттах определяют как предельную. Если интенсивность нагрузки превысит Ттах, процессор не сможет выполнить необходимый объем работы и перейдет в режим кратко­временной перегрузки.

Существуют различные программные средства сглаживания крат­ковременных всплесков нагрузки, Например, во время таких вспле­сков могут приостанавливаться те программы периодического тех­обслуживания, которым обычно присваивают низкий приоритет, а их выполнение производится тогда, когда время процессора не занято опросом или обработкой вызовов. В левой части рис. 9.2, где интен­сивность нагрузки нулевая, для техобслуживания доступно 50% ра­бочего времени, а в правой его части для задач техобслуживания рабочего времени не остается. Однако очень длительный период повышенной нагрузки может привести к переполнению очереди и к аварийному отказу всей программной системы.

Рассмотрим интенсивность нагрузки, равную половине макси­мальной величины. В результате интерполяции между двумя край­ними точками на рис. 9.2 получим, что опрос занимает 50% рабоче­го времени процессора, обработка вызовов - 25% этого времени, а 25% остается для техобслуживания. Хотя рис. 9.2 хорошо иллюст­рирует зависимость распределения рабочего времени процессора от интенсивности телефонной нагрузки, он не показывает поведе­ние программ в реальном времени. В 1 ESS и в машинах «Нева» оно определяется приоритетами.

В 1 ESS имеются приоритеты базового уровня, обозначаемые бу­квами от А до Е и I. Для предотвращения перегрузки периодическо­му сканированию абонентских линий назначается низкий приоритет D. В условиях обычной нагрузки сканирование абонентских линий выполняется каждые 100 мс. Когда процессор очень занят, время между двумя запусками программ приоритета D может достигать 700 мс, и при этом экономятся шесть циклов сканирования. Единст­венная расплата за такую экономию -малозаметная задержка сиг­нала ответа станции при перегрузке системы.

Практически такое же решение было реализовано в конце 80-х годов в АТС DX-200, а затем и в АТСЦ-90, после того как лавиной телефонных поздравлений по случаю 8 Марта была остановлена одна из первых цифровых АТС в стране. Эффект, который дает это реше­ние, иллюстрирует рис. 9.3.

Рис. 9.3 Эффект программного управления нагрузкой АТС

И все же разработчики 1 ESS не только сильно недооценили труд­ности разработки программного обеспечения, но и сильно пере­оценили производительность своего процессора 1Е. Эти два важ­нейших вопроса, конечно, тесно связаны - если программа оказы­вается длиннее, чем ожидалось, время ее выполнения, по-види­мому, становится больше, и требуется больше рабочего времени процессора, чем ожидалось. Хотя было обещано, что процессор 1Е будет управлять коммутационной станцией емкостью несколь­ко сотен тысяч абонентских линий, первоначально процессор 1Е с трудом обслуживал несколько тысяч абонентских линий и вскоре был заменен более быстродействующим процессором 1 А. В отли­чие от этого, все процессоры «Нева» в до сих пор успешно рабо­тающих междугородных АМТС «Кварц», как и в выпущенном всего в единственном экземпляре транзитном узле ИВТУ, не достигли предельных значений производительности. Разные судьбы машин 1ESS и машин «Нева» были обусловлены отнюдь не техническими решениями.

9.4 Технологические аспекты разработки программного обеспечения АТС

1ESS и ИВТУ были новаторскими работами, обобщенный опыт которых дал начало современной теории проектирования программ­ного обеспечения реального времени.

Независимо от используемой теоретической модели, жизненный цикл программного обеспечения системы коммутации разделяется на четыре фазы:

• разработка,

• тестирование,

• внедрение,

• сопровождение,

из которых в этом параграфе основное внимание уделяется первой.

Одной из ранних моделей разработки программного обеспече­ния является модель водопада (waterfall model), или, иначе, - кас­кадная модель, представленная на рис. 9.4. Дальнейшая эволюция этой модели, обусловленная, в частности, рассматриваемыми в сле­дующей главе требованиями надежности и эффективности эксплуа­тационного управления системами коммутации, а также необходи­мостью оперативного ввода новых телекоммуникационных услуг на основе их быстрого макетирования, привел к V-модели, являющей­ся развитием каскадной модели и представленной на рис. 9.5.

Обе эти модели предполагают, что любая фаза работы заверша­ется до того, как начнется работа следующей фазы. Однако сегодня при разработке ПО используется методология объектно-ориенти­рованного программирования, для которой больше подходит пред­ложенная Б.Боэмом [21] спиральная модель, приведенная на рис. 9.6 и соответствующая итерационному процессу создания ПО пу­тем последовательных приращений.

Не вдаваясь в детали других фаз жизненного цикла ПО, сосре­доточимся на процессе разработки телекоммуникационного про­граммного обеспечения. В схеме этого процесса, приведенной на рис. 9.7, предусмотрена иерархическая декомпозиция процесса разработки на последовательность шагов, уточняющих проект. Та­кими укрупненными шагами (уровнями проектирования) являются анализ и формализация требований и интерфейсов коммутацион­ного оборудования (R-уровень), определение архитектуры (сис­темной и функциональной) и модульной структуры ПО (А-уровень), разработка SDL-спецификаций модулей (блоков, процессоров, процедур, макросов, структур данных) и межмодульных интерфей­сов (S-уровень) и собственно программирование и отладка про­грамм (Р-уровень).

Уровни проектирования различаются как степенью конкретизации (возрастающей сверху вниз), так и языковыми средствами описания. Представление системы ПО на вышестоящем уровне является в из­вестном смысле «общим прародителем» семейства ее представле­ний на нижестоящих уровнях. На всех уровнях проектирования (а не только на S-уровне) производится последовательная спецификация задач, которые решает ПО. Под спецификацией здесь понимается описание в терминах, характерных для самой задачи, а не для ее реа­лизации, служащее основой для дальнейшей детализации и разра­ботки телекоммуникационного ПО. Можно считать, что каждый уро­вень проектирования получает спецификации от вышестоящего уров­ня и, в свою очередь, вырабатывает данные необходимые, для спе­цификации одного (или более) из нижестоящих уровней. Отличитель­ные свойства спецификаций - однозначность, точность, формаль­ность, понятность и читаемость. Как отмечено в [44], язык програм­мирования более высокого уровня может считаться языком специ­фикаций по отношению к языку более низкого уровня. При этом спе­цификация программного модуля не обязана быть короче самого модуля, ибо от нее требуется не краткость, а точность и понятность.

Определение и спецификация требований к ПО узла коммута­ции являются основными задачами R-уровня проектирования. На этом уровне разрабатываются технические требования, структур­ная схема станции, интерфейсы ПО с коммутационным оборудо­ванием и т.д. Языком описания, как правило, служит естественный язык со всеми присущими ему недостатками - неоднозначностью, связанной с тем, что естественный язык недостаточно точен для описания программных систем, и разные разработчики могут по-разному понять одну и ту же фразу технического задания, и непол­нотой описания ПО, которая усугубляется тем, что при разработке большой и сложной системы телекоммуникационных программ проходит много времени, прежде чем становится ясно, какой ин­формации R-уровня недостает.

Еще одна трудность, возникающая на R-уровне проектирования, -невозможность удержать семантику описания требований на оди­наковом уровне детализации. В результате одни описания R-уровня оказываются несколько туманными, другие - излишне детализиро­ванными, предоставляя элементы реализации, причем, возможно, не самой удачной, выбранной без рассмотрения остальных частей системы и не позволяющей разработчикам следующих уровней про­ектирования использовать эффективные структуры данных или прие­мы программирования.

После завершения R-уровня проектирования, т.е. когда точная внешняя спецификация системы программного управления комму­тационного узла заменит ее неформальное описание, начинается разработка архитектуры ПО (А- уровень).

А-уровень проектирования можно условно разделить на два подуровня - разработка функциональной архитектуры и разработка системной архитектуры. Принципы проектирования этих подуров­ней претерпели за последние годы принципиальные изменения. Вычурные системные решения, хаотические управляющие структу­ры и тысячестрочные подпрограммы сменились тщательно опреде­ленными и хорошо документированными функциональными моду­лями. Произошло заметное смещение критериев проектирования -алгоритмам управления ресурсами управляющих процессов отво­дится значительно меньшая роль, чем проблемам структуризации системы и взаимодействия процессов. На том же А-уровне проек­тирования разрабатывается структурная модель программной сис­темы, состоящая из иерархии содержательных функций, эффект выполнения которых влияет на функционирование коммутационно­го узла и обслуживание вызовов. Такая структурная модель в реко­мендованном ITU-T языке спецификаций и описаний SDL называет­ся диаграммой дерева блоков. Блок представляет собой наиболее крупный объект в SDL, который, в свою очередь, содержит один или несколько процессов. Разбиение системы ПО на составные части делается таким образом, чтобы каждая из частей была небольшой, удобной для восприятия и соответствующей естественному функ­циональному разбиению, и чтобы связи между частями, возникаю­щие в результате разбиения, были как можно более слабыми. На ка­ждом этапе разбиения специфицируются также каналы, входные сигналы, выходные сигналы и данные.

Программная документация А- уровня служит исходными дан­ными для проектирования SDL-спецификаций программных про­цессов, процедур и макросов, что в отечественной литературе ино­гда именуется алгоритмическим обеспечением АТС. Неформаль­но алгоритм можно определить как совокупность правил, опреде­ляющих эффективную процедуру решения любой задачи из неко­торого заданного класса задач. Сам термин произошел от араб­ского имени великого узбекского математика IX века Мухаммеда аль Хорезма и, следовательно, известен достаточно давно, но как математические объекты алгоритмы исследуются с 30-х годов про­шлого столетия. Уточнения понятия алгоритма основываются, в ча­стности, на понятиях частично-рекурсивной функции или машины Тьюринга. Строго говоря, составление алгоритма программного управления АТС является в математическом смысле алгоритмиче­ски неразрешенной проблемой, т.к. область аргументов такого ал­горитма обязательно должна включать в себя состояния и теку­щие значения реального времени функционирования узла комму­тации. С другой стороны, известен так называемый тезис Черча, состоящий в том, что любая вычислимая арифметическая функция является частично-рекурсивной. Следовательно, алгоритмическая неразрешимость проблемы составления алгоритма программно­го управления АТС вытекает из простых мощностных соображений: всех арифметических (числовых) функций - континиум, а частич­но-рекурсивных - счетное множество. Тем не менее, термин алго­ритмическое обеспечение прочно укоренился в лексиконе специа­листов по программному обеспечению систем коммутации. Интуи­тивно под этим термином понимаются спецификации телекомму­никационного программного обеспечения. Именно в таком смыс­ле этот термин используется и в настоящей книге.

Детальное проектирование S-уровня включает в себя уточнение спецификаций интерфейсов программных модулей и структур дан­ных и проектирование SDL-диаграмм модулей. При уточнении ин­терфейсов окончательно определяются порядок и структура пара­метров, глобалов и сообщений, составляющих интерфейс. Проек­тирование SDL- диаграмм на S-уровне тоже выполняется сверху вниз методом пошаговых уточнений каналов, сигналов, процессов, про­цедур, макроопределений. Точно так же, как конструкторские чер­тежи, например, в машиностроении, SDL-диаграммы - это не про­сто картинки, а законченный и богатый язык.

Механизмы SDL просты и обладают большой выразительной си­лой, что делает SDL естественным и удобным для применения. Тре­буется совсем небольшая практика, что бы научиться читать на SDL и точно воспринимать информационное содержание, передаваемое графическими обозначениями и словами языка. Однако, будучи язы­ком с точно определенной семантикой, SDL налагает жесткие огра­ничения на правила толкования смысла спецификаций и на правила написания SDL-диаграмм.

Можно напомнить, что разработка языка SDL проводится ITU-T с начала 70-х годов. Первая версия SDL6bma опубликована в 1977 г., вторая - в 1982 г., а третья, расширенная и модернизированная, -в 1985 г. Этим версиям присвоены наименования, соответственно, SDL-76, SDL-80, SDL-84. Первые версии представляли собой сред­ства полуформального описания систем с помощью графического псевдокода, но постепенно возможности формального структури­рованного описания систем развились существенно глубже, вплоть до создания полностью формализованных и выполнимых специфи­каций ПО узлов коммутации. В таблице 9.1 приведены основные опе­раторы графической версии SDL.

Завершающим шагом разработки ПО является кодирование и от­ладка программ (Р-уровень проектирования). Именно Р-уровень многие называют программированием. В течение этого этапа про­граммная разработка конвертируется в коды, которые могут испол­няться в управляющих процессорах. Первые системы программно­го управления коммутацией создавались на языке Ассемблер, но значительное улучшение характеристик процессоров, в полном со­ответствии с законом Мура, привело к возможности эффективного использования языков высокого уровня, в число которых входит по­пулярный для телекоммуникационных приложений язык Си++.

Таблица 9.1 Символы SDL


Окончание табл. 9.1

 






© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.