A biblioteca cliente é quase segura com threads. O maior
problema é que a subrotinas em net.c
que
leem dos sockets não são seguras a interrupções. Isto foi
feito pesando que você pudesse desejar ter o seu próprio
alarme que possa quebrar uma longa leitura no servidor. Se você
instalar manipuladores de interrupção para a interrupção
SIGPIPE
, o manipulador socket deve ser segura
com threads.
Nos binários antigos que distribuímos em nosso web site (http://www.mysql.com/), as bibliotecas clientes não estão normalmente compiladas com a opção de segurança com thread (os binários são complados com segurança com thread por padrão). Distribuições binárias mais novas devem ter uma biblioteca normal e uma segura com threads.
Para termos um cliente em threads onde você pode interromper o
cliente a partir de outras threads a definir tempo limites ao
falar com o servidor MySQL, você deve utilizar as bibliotecas
-lmysys
, -lmystrings
, e
-ldbug
e o código
net_serv.o
que o servidor utiliza.
Se você não precisar de insterrupções ou de tempos limites,
você pode apenas compilar um biblioteca cliente
(mysqlclient_r)
segura com threads e
utilizá-las. See Secção 12.1, “API C do MySQL”. Neste caso você não
precisa se preocupar com o arquivo objeto
net_serv.o
ou outras bibliotecas MySQL.
Quando usar um cliente em thread e você quiser utilizar tempos
limite e interrupções, você pode ter um grande uso das
rotinas no arquivo thr_alarm.c
. Se você
estiver utilizando rotinas da biblioteca
mysys
, a única coisa que você deve lembrar
é de chamar primeiro my_init()
! See
Secção 12.1.10, “Descrição das Funções de Threads da API C”.
Todas as funções com excessão de
mysql_real_connect()
são seguras com thread
por padrão. As anotações seguintes descrevem como compilar
uma biblioteca cliente segura com thread e utilizá-la de
maneira segura. (As anotações abaixo para
mysql_real_connect()
na verdade se aplicam
também a mysql_connect()
, mas como
mysql_connect()
está obsoleto, você deve
utilizar mysql_real_connect()
.)
Para tornar mysql_real_connect()
seguro com
thread, você deve recompilar a biblioteca cliente com este
comando:
shell> ./configure --enable-thread-safe-client
Isto irá criar uma biblioteca cliente
libmysqlclient_r
. (Assumindo que o seu SO
tenha a função gethostbyname_r()
segura com
thread). Esta biblioteca é segura com thread por conexão.
Você pode deixar duas threads compartilharem a mesma conexão
com os seguintes cuidados:
Duas threads não podem enviar uma consaulta ao servidor
MySQL ao mesmo tempo na mesma conexão. Em particular, você
deve assegurar que entre um mysql_query()
e mysql_store_result()
nenhuma outra
thread está usando a mesma conexão.
Várias threads podem acessár resultados diferentes que
são recuperados com
mysql_store_result()
.
Se você utilizar mysql_use_result
, você
terá que assegurar que nenhuma outra thread está usando a
mesma conexão até que o resultado seja fechado. No
entanto, é melhor para clientes em threads que compartilham
a mesma conexão utilizar
mysql_store_result()
.
Se você quiser utilizar múltiplas threads na mesma
conexão, você deve ter uma trava mutex na combinação das
chamadas mysql_query()
e
mysql_store_result()
. Uma vez que
mysql_store_result()
esteja pronto, a
trva pode ser liberada e outras threads podem utilizar a
mesma conexão.
Se você programa com threads POSIX, você pode utilizar
pthread_mutex_lock()
e
pthread_mutex_unlock()
para estabelecer e
liberar uma trava mutex.
Você precisa saber o seguinte se você tiver uma thread que estiver chamando funções MySQL que não criaram a conexão ao banco de dados MySQL:
Quando você chamar mysql_init()
ou
mysql_connect()
, MySQL irá criar um
variável especica da thread para a thread que é utilizada pela
bibklioteca de depuração (entre outra coisas).
Se você chamar uma função MySQL, antes da thread chamar
mysql_init()
ou
mysql_connect()
, a thread não terá as
variáveis específicas de thread necessárias alocadas e você
acabará finalizando com uma descarga de memória mais cedo ou
mais tarde.
Para fazer que as coisas funcionem suavemente você tem que fazer o seguinte:
Chama my_init()
no início do seu
programa se for chamar qualquer outra função MySQL antes
de chamar mysql_real_connect()
.
Chame mysql_thread_init()
no manipulador
de thread antes de chamar qualquer outra função MySQL.
Na thread, chame mysql_thread_end()
antes
de chamar pthread_exit()
. Isto irá
liberar a memória usada pelas variáveis específicas da
thread do MySQL.
Você pode obter alguns erros devido a símbolos indefinidos ao
ligar seu cliente com libmysqlclient_r
. Na
maioria dos casos isto ocorre por não estar incluída a
biblioteca de threads na linha de ligação/compilação.
This is a translation of the MySQL Reference Manual that can be found at dev.mysql.com. The original Reference Manual is in English, and this translation is not necessarily as up to date as the English version.