Чтение онлайн

ЖАНРЫ

Язык программирования Python
Шрифт:

Таким образом, в примерах, используемых в этой лекции, вместо sqlite можно применять, например, psycopg: результат должен быть тем же, если, конечно, соответствующий модуль был установлен.

Однако в общем случае при переходе с одной СУБД на другую могут возникать нестыковки, даже, несмотря на поддержку одной версии DB–API. Например, у модулей могут различаться paramstyle. В этом случае придется немного переделать параметры к вызову execute. Могут быть и другие причины, поэтому переход на другую СУБД следует тщательно тестировать.

Иметь интерфейс DB–API могут не только базы данных. Например, разработчики проекта fssdb стремятся построить DB–API 2.0 интерфейс к… файловой

системе.

Несмотря на достаточно хорошие теоретические основы и стабильные реализации, реляционная модель — не единственная из успешно используемых сегодня. К примеру, уже рассматривался язык XML и интерфейсы для работы с ним в Python. Древовидная модель данных XML для многих задач является более естественной, и в настоящее время идут исследования, результаты которых позволят работать с XML так же легко и стабильно, как с реляционными СУБД. Язык программирования Python — один из полигонов этих исследований.

Решая конкретную задачу, разработчик программного обеспечения должен сделать выбор средств, наиболее подходящих для решения задачи. Очень многие подходят к этому выбору с предвзятостью, выбирая неоптимальную (для данной задачи или подзадачи) модель данных. В результате данные, которые по своей природе легче представить другой моделью, приходится хранить и обрабатывать в выбранной модели, зачастую невольно моделируя более естественные структуры доступа и хранения. Так, XML можно хранить в реляционной БД, а табличные данные — в XML, однако это неестественно. Из–за этого сложность и подверженность ошибкам программного продукта возрастают, даже если использованные инструменты высокого качества.

Заключение

В рамках данной лекции были рассмотрены возможности связи Python с системами управления реляционными базами данных. Для Python разработан стандарт, называемый DB–API (версия 2.0), которого должны придерживаться все разработчики модулей сопряжения с реляционными базами данных. Благодаря этому API код прикладной программы становится менее зависимым от марки используемой базы данных, его могут понять разработчики, использующие другие базы данных. Фактически DB–API 2.0 описывает имена функций и классов, которые должен содержать модуль сопряжения с базой данных, и их семантику. Модуль сопряжения должен содержать класс объектов–соединений с базой данных и класс для курсоров — специальных объектов, через которые происходит коммуникация с СУБД на прикладном уровне.

Здесь была использована СУБД SQLite и соответствующий модуль расширения Python для сопряжения с этой СУБД — sqlite, так как он поддерживает DB–API 2.0 и достаточно прост в установке. С его помощью были продемонстрированы основные приемы работы с базой данных: создание и наполнение таблиц, выполнение выборок и анализ полученных данных.

В конце лекции дан список других пакетов и модулей, которые позволяют Python–программе работать со многими современными СУБД.

11. Лекция: Многопоточные вычисления.

В этой лекции рассматриваются вопросы взаимодействия потоков (нитей) в рамках одной программы. Вводятся основные понятия (семафоры, очереди, блокировки). Делается попытка объяснить особенности параллельного программирования на основе модели многопоточности.

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

В современной операционной системе, даже не выполняющей ничего особенного, могут одновременно работать несколько процессов (processes). Например, при запуске программы запускается новый процесс. Функции для управления процессами можно найти в стандартном модуле os языка Python. Здесь же речь пойдет о потоках.

Потоки управления (threads) образуются и работают в рамках одного процесса.

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

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

Одним из классических средств согласования потоков являются объекты, называемые семафорами. Семафоры не допускают выполнения некоторого участка кода несколькими потоками одновременно. Самый простой семафор — замок (lock) или mutex (от английского mutually exclusive, взаимоисключающий). Для того чтобы поток мог продолжить выполнение кода, он должен сначала захватить замок. После захвата замка поток выполняет определенный участок кода и потом освобождает замок, чтобы другой поток мог его получить и пройти дальше к выполнению охраняемого замком участку программы. Поток, столкнувшись с занятым другим потоком замком, обычно ждет его освобождения.

Поддержка многопоточности в языке Python доступна через использование ряда модулей. В стандартном модуле threading определены нужные для разработки многопоточной (multithreading) программы классы: несколько видов семафоров (классы замков Lock, RLock и класс Semaphore) и другие механизмы взаимодействия между потоками (классы Event и Condition), класс Timer для запуска функции по прошествии некоторого времени. Модуль Queue реализует очередь, которой могут пользоваться сразу несколько потоков. Для создания и (низкоуровневого) управления потоками в стандартном модуле thread определен класс Thread.

Пример многопоточной программы

В следующем примере создается два дополнительных потока, которые выводят на стандартный вывод каждый свое:

Листинг

import threading

def proc(n):

print «Процесс», n

p1 = threading.Thread(target=proc, name=«t1», args=[«1»])

p2 = threading.Thread(target=proc, name=«t2», args=[«2»])

p1.start

p2.start

Сначала получается два объекта класса Thread, которые затем и запускаются с различными аргументами. В данном случае в потоках работает одна и та же функция proc, которой передается один аргумент, заданный в именованном параметре args конструктора класса Thread. Нетрудно догадаться, что метод start служит для запуска нового потока. Таким образом, в приведенном примере работают три потока: основной и два дополнительных (с именами «t1» и «t2»).

Поделиться с друзьями: