Como Fazer um Cliente em Threads


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. Leia "API C do MariaDB". 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()! Leia "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:

Você precisa saber o seguinte se você tiver uma thread que estiver chamando funções MariaDB que não criaram a conexão ao Banco de Dados MariaDB:

Quando você chamar mysql_init() ou mysql_connect(), MariaDB 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:

  1. Chama my_init() no início do seu programa se for chamar qualquer outra função MariaDB antes de chamar mysql_real_connect().
  2. Chame mysql_thread_init() no manipulador de thread antes de chamar qualquer outra função MariaDB.
  3. 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 MariaDB.

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.

Retornar