本节为编写使用 MySQL C API 中线程相关函数的客户端程序提供指导。有关这些函数的更多信息,请参阅
第 8.2 节,“C API 线程函数说明”。有关使用它们的源代码示例,请查看
client
MySQL 源代码分发目录:
mysqlimport 的源代码在与该
--use-threads
选项 关联的代码中使用线程 。mysqlslap 的源代码使用线程来设置并发工作负载,以测试高负载下的服务器操作。
作为线程编程的替代方案,应用程序可能会发现异步(非阻塞)C API 函数很有用。这些功能使应用程序能够向服务器提交多个未完成的请求,并确定每个请求何时完成使用轮询。有关详细信息,请参阅 第 7 章,C API 异步接口。
如果在将线程程序链接到 MySQL 客户端库时发生未定义引用错误,最可能的原因是您没有在链接/编译命令中包含线程库。
客户端库几乎是线程安全的。最大的问题是sql/net_serv.cc
从套接字读取的子程序不是中断安全的。这样做的想法是,您可能希望拥有自己的警报来中断对服务器的长时间读取。如果为
SIGPIPE
中断安装中断处理程序,套接字处理应该是线程安全的。
为避免在连接终止时中止程序,MySQLSIGPIPE
在第一次调用
mysql_library_init()
、
mysql_init()
或
时阻塞mysql_connect()
。要使用您自己的
SIGPIPE
处理程序,请先调用
mysql_library_init()
,然后安装您的处理程序。
客户端库对每个连接都是线程安全的。两个线程可以共享相同的连接,但需要注意以下几点:
-
除非您使用前面提到的异步 C API 函数,否则多个线程不能在同一连接上同时向 MySQL 服务器发送查询。特别是,您必须确保在对
mysql_real_query()
(ormysql_query()
) 的调用之间和mysql_store_result()
在一个线程中,没有其他线程使用相同的连接。为此,请在您的mysql_real_query()
(ormysql_query()
) 和mysql_store_result()
调用对周围使用互斥锁。返回后mysql_store_result()
,可以释放锁,其他线程可以查询同一个连接。如果使用 POSIX 线程,则可以使用
pthread_mutex_lock()
andpthread_mutex_unlock()
来建立和释放互斥锁。笔记如果您检查 MySQL 源代码分发中的程序,您将看到对and 的调用,而不是对
pthread_mutex_lock()
and的调用。后面的函数在 头文件中定义并映射到特定于平台的互斥函数。pthread_mutex_unlock()
native_mutex_lock()
native_mutex_unlock()
thr_mutex.h
多个线程可以访问使用 检索的不同结果集
mysql_store_result()
。要使用
mysql_use_result()
,您必须确保在结果集关闭之前没有其他线程使用相同的连接。但是,共享同一连接的线程客户端最好使用mysql_store_result()
.
如果线程不创建与 MySQL 数据库的连接,而是调用 MySQL 函数,请考虑以下因素:
当您调用 时mysql_init()
,MySQL 会为调试库(除其他事项外)使用的线程创建一个特定于线程的变量。如果您在线程调用之前调用 MySQL 函数
mysql_init()
,则该线程没有必要的线程特定变量,您迟早可能会遇到核心转储。为避免出现问题,您必须执行以下操作:
mysql_library_init()
在任何其他 MySQL 函数之前调用 。它不是线程安全的,因此在创建线程之前调用它,或者使用互斥锁保护调用。在调用任何 MySQL 函数之前安排
mysql_thread_init()
在线程处理程序中提前调用。(如果你打电话mysql_init()
,它会打电话mysql_thread_init()
给你。)在线程中,先调用
mysql_thread_end()
再调用pthread_exit()
。这释放了 MySQL 线程特定变量使用的内存。
前面的注意事项
mysql_init()
也适用于
mysql_connect()
调用
mysql_init()
.