8.4.8 Как создать клиентскую программу с потоками
8.4.8 Как создать клиентскую программу с потоками
Клиентская библиотека почти безопасна при использовании в мультипоточном
режиме. Наибольшая проблема заключается в том, что функции в `net.c',
читающие из сокетов, не поддерживают прерываний. Они были спроектированы
исходя из предположения, что пользователь может захотеть иметь свой
собственный аварийный сигнал, который способен прерывать слишком долгое
чтение с сервера. При установке обработчиков прерываний для прерывания
SIGPIPE управление сокетами должно быть поддерживающим потоки.
В более ранних бинарных поставках MySQL, которые мы (разработчики MySQL)
распространяли с нашего веб-сайта (http://www.mysql.com/), клиентские
библиотеки обычно не компилировались с возможностью поддержки потоков
(бинарные поставки для Windows по умолчанию компилируются как
поддерживающие потоки). Более новые бинарные поставки должны иметь как
нормальную, так и поддерживающую потоки клиентскую библиотеку.
Чтобы получить поддерживающую потоки клиентскую программу с возможностью
прерывать ее из других потоков и устанавливать блокировки по времени при
соединении с сервером MySQL, необходимо использовать библиотеки -lmysys,
-lmystrings и -ldbug libraries, а также код `net_serv.o', используемый
данным сервером.
Если нет необходимости в прерываниях или временных блокировках, то можно
просто скомпилировать поддерживающую потоки клиентскую библиотеку
(mysqlclient_r) и использовать ее (see section 8.4 Интерфейс C для MySQL). В этом случае
нет необходимости заботиться об объектном файле net_serv.o или других
библиотеках MySQL.
Если необходимо применять временные блокировки и прерывания при
использовании поддерживающего потоки клиента, то можно с успехом
использовать подпрограммы из файла `thr_alarm.c'. При использовании
подпрограмм из библиотеки mysys следует помнить только о том, что сначала
следует вызвать функцию my_init()! See section 8.4.4 Описания функций C, связанных с потоками.
Все функции, за исключением mysql_real_connect(), по умолчанию являются
поддерживающими потоки. Ниже приводятся рекомендации, как следует
компилировать поддерживающую потоки клиентскую библиотеку и использовать
ее в этом режиме (замечания по функции mysql_real_connect() справедливы
также и для функции mysql_connect(), но поскольку функция mysql_connect()
не рекомендуется, то в любом случае следует использовать функцию
mysql_real_connect()).
Для того чтобы сделать функцию mysql_real_connect() поддерживающей потоки,
необходимо перекомпилировать клиентскую библиотеку со следующей командой:
shell> ./configure --enable-thread-safe-client
Это создаст поддерживающую потоки клиентскую библиотеку libmysqlclient_r
(предполагается, что данная операционная система включает поддерживающую
потоки функцию gethostbyname_r()). Эта библиотека является поддерживающей
потоки для данного соединения. Можно позволить двум потокам использовать
одно и то же соединение со следующими оговорками:
-
Два потока не могут посылать запрос серверу MySQL в одно и то же время
на одном и том же соединении. В особенности необходимо быть уверенным,
что в промежутках между вызовом функций mysql_query() и
mysql_store_result() никакой другой поток не использует это же
соединение.
-
Многие потоки имеют доступ к различным результирующим наборам данных,
извлекаемых функцией mysql_store_result().
-
При использовании функции mysql_use_result необходимо быть уверенным,
что никакой другой поток не использует это же соединение, пока данный
результирующий набор не будет обработан. Однако действительно
наилучший вариант для потоковых клиентов, совместно использующих одно
и то же соединение, - это применять функцию mysql_store_result().
-
Если необходимо использовать большое количество потоков на одном и том
же соединении, то следует иметь синхронизирующую блокировку в
отношении вызова комбинации функций mysql_query() и
mysql_store_result(). Как только выполнение функции
mysql_store_result() заканчивается, данная блокировка может сниматься
и другие потоки могут запрашивать это же самое соединение.
-
Если вы программируете с использованием потоков POSIX, то можно
использовать функции pthread_mutex_lock() и pthread_mutex_unlock() для
установки и освобождения синхронизирующей блокировки.
Необходимо знать следующее: если имеется вызываемый функцией MySQL поток,
который не создавал данное соединение с базой данных MySQL, то:
При вызове функций mysql_init() или mysql_connect() MySQL создаст
специальные переменные для этого потока, которые (среди прочих применений)
используются библиотекой отладки.
При вызове функции MySQL до того, как поток вызвал функции mysql_init()
или mysql_connect(), данный поток в этом случае не будет иметь необходимых
специальных переменных потока и, вероятно, программа рано или поздно умрет
с дампом оперативной памяти.
Для более плавной работы программы необходимо выполнить следующие
действия:
-
Вызвать функцию my_init() при запуске данной программы, если она
вызывает какую-либо другую функцию MySQL до вызова функции
mysql_real_connect().
-
Вызвать функцию mysql_thread_init() в обработчике потока до вызова
иной функции MySQL.
-
В данном потоке вызвать функцию mysql_thread_end() перед вызовом
pthread_exit(). Это освободит память, занятую специальными переменными
потока для MySQL.
Следует учитывать, что можно получить некоторые ошибки из-за наличия
неопределенных символов при связывании клиента с библиотекой
libmysqlclient_r. В большинстве случаев это происходит вследствие того,
что в строку связывания/компилирования не включены библиотеки потока.
Forekc.ru
Рефераты, дипломы, курсовые, выпускные и квалификационные работы, диссертации, учебники, учебные пособия, лекции, методические пособия и рекомендации, программы и курсы обучения, публикации из профильных изданий
|