Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология
Образование Политология Производство Психология Стандартизация Технологии


Схема работы chat-сервера и chat-клиента



Сервер

Работа сервера начинается с перехода в состояние ожидания запроса на установление соединения от клиента. Затем сервер входит в цикл, в котором он получает и отображает строки текста от клиентов.

Клиент

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

Потоки управления

Т.к. сервер должен работать одновременно с каждым клиентом, рекомендуется использовать либо неблокирующие сокеты (читать в цикле данные из каждого сокета по-очереди), либо для каждого клиента запускать отдельный параллельный поток thread операционной системы, который бы занимался обменом сообщениями с клиентом. Необходимые для работы с потоками функции содержатся в модулях thread и threading.

Потоки управления образуются и живут в рамках одного процесса. В однопоточном приложении есть только один поток управления: при запуске программы он последовательно исполняет встреченные в программе операторы. В любой момент времени интерпретатор Python знает, какую команду исполнить, а после исполнения команды – куда передать управление. Эта ниточка непрерывна все время исполнения программы и обрывается только по завершении программы.

Представим теперь, что в некоторой точке ниточка раздваивается и каждый поток пошел своим путем, возможно, еще несколько раз раздваиваясь по пути. (При этом один из потоков всегда остается главным, и его завершение означает завершение всей программы.) В каждый момент времени интерпретатор знает, какую команду какой поток должен выполнить, и уделяет внимание каждому потоку. Однако такое незначительное усложнение исполнения программы приводит к тому, что нам необходимы механизмы для согласования деятельности потоков. Например, нельзя допускать, чтобы потоки одновременно изменяли один и тот же объект. На помощь приходят специальные объекты, называемые семафорами. Семафоры позволяют исключать исполнение одного и того же участка кода несколькими потоками одновременно. Самый простой двоичный семафор – замок(lock) или mutex. Чтобы поток мог продолжить исполнение кода, он должен сначала овладеть замком. После этого он выполняет некоторый участок кода и снимает замок, чтобы другой поток (возможно, уже сделавший запрос на данный замок) мог его получить и пройти дальше к выполнению охраняемого замком участка программы.


Класс threading.Thread позволяет назначить действия, которые должны выполняться в отдельном потоке, и имеет следующий конструктор:

threading.Thread(group, target, name, args=(), kwargs={}) -> object

где group – группа потоков, target – функция, метод или другой объект, позволяющий вызов, именно он вызывается при запуске потока, name – имя потока, args и kwargs – соответственно позиционные и именованные аргументы для вызова потока.

Приведем некоторые методы объектов класса threading.Thread. Метод start() запускает поток.(Метод не имеет параметров и ничего не возвращает.) Метод run() используется для вызова в отдельном потоке. Получает свое значение из параметра target конструктора класса. При вызове используются args и kwargs, заданные в конструкторе. Метод join([time]) ожидает завершения потока. Поток, который вызывает этот метод приостанавливается. Значение time задает время ожидания, после которого приостановленный поток продолжает свою работу. Метод getName() возвращает имя потока, метод setName(name) устанавливает имя потока. Метод isAlive() возвращает значение `истина`, если поток работает.

Класс threading.Lock – простейший замок, который имеет два состояния (он может быть либо открыт, либо заперт). Объект Lock имеет два основных метода acquire() ( с помощью этого метода поток делает запрос на запирание замка) и release() (для снятия замка). Метод locked() возвращает статус замка: 0 – свободен, 1 – занят.

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

В некоторых случаях (например, в рекурсивных функциях) необходимо, чтобы один и тот же поток имел возможность запрашивать замок даже в случае, если он им уже обладает. Объект класса threading.RLock имеет эту возможность, и потому может сколько угодно раз запрашивать замок методом acquire() и столько же раз снимать методом release(). Первоначально замок находится в открытом состоянии и не принадлежит ни одному потоку. Замок возвращается в исходное незапертое состояние только после одинакового числа запросов и освобождений. При этом все остальные потоки, которые запрашивают замок, остаются в состоянии ожидания.

Семафоры – класс threading.Semaphore – представляют собой более общий механизм синхронизации потоков, чем замки. С их помощью в критическую часть программы допускаются несколько потоков. Семафор ведет счетчик запросов, который при каждом запросе acquire() уменьшается на единицу, а при каждом release() – увеличивается на единицу. Счетчик не может стать меньше нуля, поэтому, если запрос поступает когда счетчик равен нулю, потоку приходится ждать, как и в случае с замками, пока один из потоков не увеличит счетчик.

Объекты класса threading.Event служат для простейшей коммуникации между потоками, при которой один поток сигнализирует о событии, тогда как другие находятся в состоянии ожидания. Объекты события имеют внутренний флаг, который может быть установлен или сброшен. При своем создании флаг находится в сброшенном состоянии. Если флаг установлен, ожидания не происходит: соответствующий поток продолжает свою работу.

Модуль thread предоставляет низкоуровневый доступ к потокам управления. В этом модуле доступны следующие функции.

Создание нового потока для исполнения функции function с кортежем аргументов args и cсловарем kwargs. Поток завершается по возврату из функции выполняется функцией thread.start_new(func, args[, kwargs]).

Функция thread.exit() возбуждает исключение SystemExit, которое, если оказалось неперехваченным, завершает исполняющийся поток.

Функция get_ident() -> id возвращает идентификатор потока, в котором исполняется эта функция.

Вызовом функции thread.allocate_lock() -> lockobj осуществляется создание объекта замка. На основе этого замка создан класс threading.Lock, поэтому методы для работы с этими объектами одинаковы.

Задание к лабораторной работе

С помощью API-интерфейса реализовать простой chat.

Каждая бригада должна написать chat-сервер и chat-клиента. Сервер должен поддерживать соединение сразу от нескольких клиентов. Обмен между клиентами осуществляется через сервер. При получении сообщения от какого-либо клиента, сервер дублирует его на своем экране и оповещает всех подсоединенных клиентов, отправляя каждому из них данное сообщение. При подсоединении нового клиента к chat-серверу, сервер оповещает каждого клиента о новом пользователе, посылая им его IP-адрес и имя.

Контрольные вопросы

1. Приведите схему взаимодействия chat-сервера и chat-клиента.

2. Что такое потоки управления, для чего они нужны и как они работают?

3. Какие проблемы возникают при использовании потоков управления и какие методы решения этих проблем существуют?

4. Опишите классы модуля threading.

5. Какие виды замков существуют? Расскажите о преимуществах и недостатках каждого из них.


Лабораторная работа №4

Создание Web-сервера.

Цель работы

Изучить технологии создания Web-серверов, работающих на основе протокола HTTP, особенности архитектуры программно обеспечения Web-браузеров и основные типы Web-документов.

Методические указания

Интерфейс браузера

World Wide Web (WWW) — крупномасштабный, оперативный репозитарий информации, в котором пользователи могут выполнять поиск с использованием интерактивной прикладной программы, называемой браузером. Большинство браузеров имеет интерфейс, организованный по принципу " указать и щелкнуть" — браузер отображает информацию на экране компьютера и позволяет перемещаться по разделам этой информации с помощью мыши. Отображаемая информация может включать и текст, и графику. Кроме того, часть информации, отображаемой на экране, выделена для указания того, что соответствующий элемент может быть выбран пользователем. При установке пользователем курсора над элементом, доступным для выбора, и щелчка кнопкой мыши браузер отображает информацию, которая соответствует выбранному элементу.

Гипермедийный документ, доступный в Web, называется страницей; главная страница организации или отдельного лица называется начальной страницей. Поскольку страница может содержать много информационных элементов, ее формат должен быть выбран очень тщательно, чтобы содержимое страницы мог интерпретировать любой браузер. В частности, браузер должен различать произвольный текст, графику и ссылки на другие страницы. Кроме того, в распоряжении автора страницы должны находиться средства описания общей компоновки документа (например, порядка, в котором должны быть представлены элементы).

Для каждой Web-страницы, содержащей гипермедийный документ, используется стандартное представление. Этот стандарт, известный под названием языка гипертекстовой разметки (HyperText Markup Language — HTML), позволяет автору страницы реализовать свои замыслы по отображению информации на странице и указать, что на ней находится.


Идентификация страницы

Вызывая браузер на выполнение, пользователь должен указать начальную страницу, к которой он хочет обратиться. Указание конкретной страницы является сложной задачей по нескольким причинам. Во-первых, в сеть Web входит много компьютеров, и страница может находиться на любом из них, во-вторых, каждый компьютер может содержать много страниц и каждой из них должно быть присвоено уникальное имя. В-третьих, Web обеспечивает отображение документов во многих форматах, поэтому браузеру должно быть дано указание, какое представление применяется на данной странице(например относится ли указанное имя к документу HTML или к изображению, хранящемуся в двоичной форме). В-четвертых, поскольку сеть Web интегрирована с другими приложениями, браузер должен иметь информацию о том, какой прикладной протокол должен применяться для доступа к странице.

Разработан синтаксический формат, который позволяет обозначить элемент данных, находящийся на удаленном компьютере. Этот синтаксический формат позволяет закодировать всю информацию в символьной строке, называемой унифицированным локатором ресурсов (Uniform Resourse Locator-URL). URL имеет следующую общую форму:

protocol: //computer_name: port/document_name

Здесь protocol – имя протокола, применяемого для доступа к документу, computer_name – доменное имя компьютера, на котором находится документ, : port – необязательный номер порта протокола, document_name – имя документа, под которым он хранится на указанном компьютере.


Поделиться:



Популярное:

Последнее изменение этой страницы: 2016-05-03; Просмотров: 762; Нарушение авторского права страницы


lektsia.com 2007 - 2024 год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! (0.018 с.)
Главная | Случайная страница | Обратная связь