27.7.3.3 编写 C API 线程 Client 端程序
本节提供有关编写使用 MySQL C API 中与线程相关的功能的 Client 端程序的指南。有关这些功能的更多信息,请参见第 27.7.11 节,“ C API 线程功能描述”。有关使用它们的源代码示例,请查看 MySQL 源发行版的client
目录:
-
mysqlimport的源代码使用与--use-threads选项关联的代码中的线程。
-
mysqlslap的源使用线程设置并发工作负载,以测试高负载下的服务器操作。
如果将线程程序链接到 MySQLClient 端库时发生未定义的引用错误,则最可能的原因是您没有在 link/compile 命令中包括线程库。
Client 端库几乎是线程安全的。最大的问题是sql/net_serv.cc
中从套接字读取的子例程不是中断安全的。这样做的想法是,您可能希望拥有自己的警报,该警报可能中断对服务器的长时间读取。如果您为SIGPIPE
中断安装中断处理程序,则套接字处理应该是线程安全的。
为了避免在连接终止时终止程序,MySQL 在第一次调用mysql_library_init(),mysql_init()或mysql_connect()时会阻止SIGPIPE
。要使用您自己的SIGPIPE
处理程序,请先调用mysql_library_init(),然后安装您的处理程序。
Client 端库是每个连接线程安全的。两个线程可以通过以下注意事项共享同一连接:
- 多个线程无法在同一连接上同时向 MySQL 服务器发送查询。特别是,您必须确保在一个线程中对mysql_query()和mysql_store_result()的调用之间,没有其他线程使用相同的连接。为此,请在一对mysql_query()和mysql_store_result()调用周围使用互斥锁。 mysql_store_result()返回后,可以释放该锁,并且其他线程可以查询相同的连接。
如果使用 POSIX 线程,则可以使用pthread_mutex_lock()
和pthread_mutex_unlock()
构建和释放互斥锁。
Note
如果检查 MySQL 源代码分发中的程序,而不是调用pthread_mutex_lock()
和pthread_mutex_unlock()
,则将看到对native_mutex_lock()
和native_mutex_unlock()
的调用。后面的函数在thr_mutex.h
头文件中定义,并 Map 到特定于平台的互斥函数。
-
多个线程可以访问使用mysql_store_result()检索的不同结果集。
-
要使用mysql_use_result(),必须确保在关闭结果集之前,没有其他线程使用相同的连接。但是,对于共享相同连接的线程 Client 端,最好使用mysql_store_result()。
如果线程没有创建与 MySQL 数据库的连接而是调用 MySQL 函数,请考虑以下因素:
当您调用mysql_init()时,MySQL 将为调试库使用的线程创建线程特定的变量(除其他外)。如果在线程调用mysql_init()之前调用 MySQL 函数,则该线程没有适当的线程特定变量,并且您迟早可能会进行核心转储。为了避免出现问题,您必须执行以下操作:
-
在执行其他任何 MySQL 功能之前,请先致电mysql_library_init()。它不是线程安全的,因此请在创建线程之前调用它,或使用互斥锁保护该调用。
-
安排在调用任何 MySQL 函数之前先在线程处理程序中调用mysql_thread_init()。 (如果您致电mysql_init(),它将为您致电mysql_thread_init()。)
-
在线程中,先调用mysql_thread_end(),再调用
pthread_exit()
。这释放了 MySQL 线程特定变量使用的内存。
先前有关mysql_init()的 Comments 也适用于mysql_connect(),它称为mysql_init()。