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 端库是每个连接线程安全的。两个线程可以通过以下注意事项共享同一连接:

如果使用 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 数据库的连接而是调用 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()