3.3 编写 C API 线程客户端程序

本节为编写使用 MySQL C API 中线程相关函数的客户端程序提供指导。有关这些函数的更多信息,请参阅 第 7.2 节,“C API 线程函数说明”。有关使用它们的源代码示例,请查看 clientMySQL 源代码分发目录:

  • mysqlimport 的源代码在与该--use-threads选项 关联的代码中使用线程 。

  • mysqlslap 的源代码使用线程来设置并发工作负载,以测试高负载下的服务器操作。

如果在将线程程序链接到 MySQL 客户端库时发生未定义引用错误,最可能的原因是您没有在链接/编译命令中包含线程库。

客户端库几乎是线程安全的。最大的问题是sql/net_serv.cc从套接字读取的子程序不是中断安全的。这样做的想法是,您可能希望拥有自己的警报来中断对服务器的长时间读取。如果为 SIGPIPE中断安装中断处理程序,套接字处理应该是线程安全的。

为避免在连接终止时中止程序,MySQLSIGPIPE在第一次调用 mysql_library_init()mysql_init()或 时阻塞mysql_connect()。要使用您自己的 SIGPIPE处理程序,请先调用 mysql_library_init(),然后安装您的处理程序。

客户端库对每个连接都是线程安全的。两个线程可以共享相同的连接,但需要注意以下几点:

如果线程不创建与 MySQL 数据库的连接,而是调用 MySQL 函数,请考虑以下因素:

当您调用 时mysql_init(),MySQL 会为调试库(除其他事项外)使用的线程创建一个特定于线程的变量。如果您在线程调用之前调用 MySQL 函数 mysql_init(),则该线程没有必要的线程特定变量,您迟早可能会遇到核心转储。为避免出现问题,您必须执行以下操作:

  1. mysql_library_init() 在任何其他 MySQL 函数之前调用 。它不是线程安全的,因此在创建线程之前调用它,或者使用互斥锁保护调用。

  2. 在调用任何 MySQL 函数之前安排 mysql_thread_init()在线程处理程序中提前调用。(如果你打电话 mysql_init(),它会打电话 mysql_thread_init()给你。)

  3. 在线程中,先调用 mysql_thread_end()再调用pthread_exit()。这释放了 MySQL 线程特定变量使用的内存。

前面的注意事项 mysql_init()也适用于 mysql_connect()调用 mysql_init().