MySQL 9.3 C API Developer Guide
This section provides guidance for writing client programs that
use the thread-related functions in the MySQL C API. For further
information about these functions, see
Section 8.2, “C API Threaded Function Descriptions”. For examples
of source code that uses them, look in the
client
directory of a MySQL source
distribution:
The source for mysqlimport uses threading
in the code associated with the
--use-threads
option.
The source for mysqlslap uses threads to set up simultaneous workloads, to test server operation under high load.
As an alternative to thread programming, applications may find the asynchronous (nonblocking) C API functions useful. These functions enable applications to submit multiple outstanding requests to the server and determine when each has finished using polling. For more information, see Chapter 7, C API Asynchronous Interface.
If undefined-reference errors occur when linking a threaded program against the MySQL client library, the most likely cause is that you did not include the thread libraries on the link/compile command.
The client library is almost thread-safe. The biggest problem is
that the subroutines in sql/net_serv.cc
that
read from sockets are not interrupt-safe. This was done with the
thought that you might want to have your own alarm that can break
a long read to a server. If you install interrupt handlers for the
SIGPIPE
interrupt, socket handling should be
thread-safe.
To avoid aborting the program when a connection terminates, MySQL
blocks SIGPIPE
on the first call to
mysql_library_init()
,
mysql_init()
, or
mysql_connect()
. To use your own
SIGPIPE
handler, first call
mysql_library_init()
, then install
your handler.
The client library is thread-safe per connection. Two threads can share the same connection with the following caveats:
Unless you are using the asynchronous C API functions
mentioned previously, multiple threads cannot send a query to
the MySQL server at the same time on the same connection. In
particular, you must ensure that between calls to
mysql_real_query()
(or
mysql_query()
) and
mysql_store_result()
in one
thread, no other thread uses the same connection. To do this,
use a mutex lock around your pair of
mysql_real_query()
(or
mysql_query()
) and
mysql_store_result()
calls.
After mysql_store_result()
returns, the lock can be released and other threads may query
the same connection.
If you use POSIX threads, you can use
pthread_mutex_lock()
and
pthread_mutex_unlock()
to establish and
release a mutex lock.
If you examine programs in a MySQL source distribution,
instead of calls to pthread_mutex_lock()
and pthread_mutex_unlock()
, you will see
calls to native_mutex_lock()
and
native_mutex_unlock()
. The latter
functions are defined in the
thr_mutex.h
header file and map to
platform-specific mutex functions.
Multiple threads can access different result sets that are
retrieved with
mysql_store_result()
.
To use mysql_use_result()
, you
must ensure that no other thread uses the same connection
until the result set is closed. However, it really is best for
threaded clients that share the same connection to use
mysql_store_result()
.
If a thread does not create the connection to the MySQL database but calls MySQL functions, take the following into account:
When you call mysql_init()
, MySQL
creates a thread-specific variable for the thread that is used by
the debug library (among other things). If you call a MySQL
function before the thread has called
mysql_init()
, the thread does not
have the necessary thread-specific variables in place and you are
likely to end up with a core dump sooner or later. To avoid
problems, you must do the following:
Call mysql_library_init()
before any other MySQL functions. It is not thread-safe, so
call it before threads are created, or protect the call with a
mutex.
Arrange for
mysql_thread_init()
to be
called early in the thread handler before calling any MySQL
function. (If you call
mysql_init()
, it calls
mysql_thread_init()
for you.)
In the thread, call
mysql_thread_end()
before
calling pthread_exit()
. This frees the
memory used by MySQL thread-specific variables.
The preceding notes regarding
mysql_init()
also apply to
mysql_connect()
, which calls
mysql_init()
.