# Главная
# О библиотеке

# Выбор дистрибутива
преимущества Linux/UNIX | основные дистрибутивы | серверный Linux | BSD | LiveCDs | прочее

# Установка и удаление программ
общие вопросы | каталоги софта | специальные случаи

# Настройка и работа
установка, загрузчики | настройка Linux | консоль | файловые системы | процессы | шеллы, русификация, коммандеры | виртуальные машины, эмуляторы

# X Window и оконные менеджеры
настройка X Window | GNOME | KDE | IceWM и др.

# Работа с текстами
редакторы | офис | шрифты, кодировки и русификация | преобразования текстовых файлов | LaTeX, SGML и др. | словари

# Графика
GIMP | фото | обработка изображений | форматы графических файлов

# Сети, администрирование
общие вопросы | Dialup & PPP | брандмауэры | маршрутизация | работа в Windows-сетях | веб-серверы | Apache | прокси-серверы | сетевая печать | прочее

# Программирование
GCC & GNU make | программирование в UNIX | графические библиотеки | Tcl | Perl | PHP | Java & C# | СУБД | CVS | прочее

# Ядро
# Мультимедиа
# Интернет
# Почта
# Безопасность
# Железо
# Разное

# Linux HowTo (как сделать)
# Книги и руководства
# Материалы на английском языке


MySQL The World's Most Popular Open Source Database # Online shop | Site map |  
CompanyProductsSupport & ConsultingTraining & CertificationDownloadsDocumentation
  BooksArticlesMailing ListsPresentationsOther Sites  
Search the MySQL manual:
MySQL Manual
  • 8 Интерфейсы для MySQL
    • 8.4 Интерфейс C для MySQL
      • 8.4.1 Типы данных C API
      • 8.4.2 Обзор функций интерфейса C
      • 8.4.3 Описание функций интерфейса C
      • 8.4.4 Описания функций C, связанных с потоками
      • 8.4.5 Описания функций C, доступных во встраиваемом сервере
      • 8.4.6 Основные вопросы и проблемы в использовании интерфейса C
      • 8.4.7 Сборка клиентских программ
      • 8.4.8 Как создать клиентскую программу с потоками
      • 8.4.9 libmysqld, встраиваемая библиотека сервера MySQL

Buy this Reference Manual in softcover from Barnes & Noble!

MySQL Reference Manual
Previous / Next / Up / Table of Contents

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(), данный поток в этом случае не будет иметь необходимых специальных переменных потока и, вероятно, программа рано или поздно умрет с дампом оперативной памяти.

Для более плавной работы программы необходимо выполнить следующие действия:

  1. Вызвать функцию my_init() при запуске данной программы, если она вызывает какую-либо другую функцию MySQL до вызова функции mysql_real_connect().
  2. Вызвать функцию mysql_thread_init() в обработчике потока до вызова иной функции MySQL.
  3. В данном потоке вызвать функцию mysql_thread_end() перед вызовом pthread_exit(). Это освободит память, занятую специальными переменными потока для MySQL.

Следует учитывать, что можно получить некоторые ошибки из-за наличия неопределенных символов при связывании клиента с библиотекой libmysqlclient_r. В большинстве случаев это происходит вследствие того, что в строку связывания/компилирования не включены библиотеки потока.

User Comments

Posted by [email protected] on Tuesday October 15 2002, @10:40am[Delete] [Edit]

Hello I'm using
"mysql Ver 11.15 Distrib 3.23.41, for pc-linux-gnu (i686)"
and there are no
mysql_thread_end(); and mysql_thread_init (); function at
"mysql.h".
Where are they?
I'll probably make a workaround - just calling
only mysql_init( NULL ) and without a call to
mysql_thread_end();
Also without a mysql_thread_init(); you probably cannot use
connection from other threads.

Posted by Nick Gaugler on Tuesday March 4 2003, @3:49pm[Delete] [Edit]

For MySQL 3.23 you have to use my_thread_init and my_thread_end.

Add your own comment.

Top / Previous / Next / Up / Table of Contents
# MySQL.com home | Site map | Contact us | Press | Jobs | Privacy policy | Trademark info | © 1995-2003 MySQL AB. All rights reserved.