代码之家  ›  专栏  ›  技术社区  ›  Isak Savo

如何从多线程并发访问MySQL

  •  20
  • Isak Savo  · 技术社区  · 15 年前

    我们正在做MySQL的一个小基准测试,我们想看看它对我们的数据的表现如何。

    该测试的一部分是查看当多个并发线程通过各种查询敲打服务器时它是如何工作的。

    这个 MySQL documentation (5.0)对于多线程客户机还不太清楚。我应该指出,我确实链接到线程安全库( libmysqlclient_r.so )

    我使用的是准备好的语句,读(选择)和写(更新、插入、删除)。

    • 我应该为每个线程打开一个连接吗?如果是的话:我该怎么做……似乎 mysql_real_connect() 返回我调用时得到的原始db句柄 mysql_init() )
    • 如果不是:如何确保结果和方法,如 mysql_affected_rows 返回正确的值,而不是与其他线程的调用冲突(互斥锁/锁可以工作,但感觉错误)
    4 回复  |  直到 10 年前
        1
  •  26
  •   chazomaticus    10 年前

    作为一个相当大的C应用程序的维护者,它可以从多个线程调用MySQL,我可以说,在每个线程中简单地建立一个新的连接没有问题。我遇到的一些警告:

    • 编辑:似乎此项目符号仅适用于版本<5.5;请参见 this page for your appropriate version : 就像你说你已经在做的,链接反对 libmysqlclient_r .
    • 呼叫 mysql_library_init() (一次,从 main() )阅读有关在多线程环境中使用的文档,了解为什么需要这样做。
    • 做一个新的 MYSQL 结构使用 mysql_init() 在每一个线程中。这有呼叫的副作用 mysql_thread_init() 为你。 mysql_real_connect() 像往常一样,在每个线程中,都有特定于线程的mysql结构。
    • 如果要创建/销毁大量线程,则需要使用 mysql_thread_end() 在每个螺纹的末端(和 mysql_library_end() 结束时 主体() )不管怎么说,这是个好习惯。

    基本上,不要分享 MySQL 结构或特定于该结构创建的任何内容(即 MYSQL_STMT s)它会像你期望的那样工作。

    这似乎比在我身上建立连接池要简单。

        2
  •  6
  •   Community Egal    7 年前

    您可以创建一个连接池。每个需要连接的线程都可以从池中请求一个空闲线程。如果没有可用的连接,那么您要么阻塞池,要么通过向池添加新连接来增加池。

    有篇文章 here 描述连接池的PRO和缺点(虽然它是基于Java的)

    编辑:这里有一个关于 connection pools in C

    edit2:这里有一个指向示例的链接 Connection Pool for MySQL 用C++编写的。(在实现自己的语句时,可能应该忽略goto语句。)

        3
  •  1
  •   Elemental    15 年前

    在我看来,从MySQL文档中可以清楚地看到,任何特定的MySQL结构都可以在线程中毫无困难地使用——使用 相同的 当状态存储在MySQL连接中时,不同线程中的MySQL结构显然会给您带来极其不可预知的结果。

    因此,或者按照上面的建议为每个线程创建一个连接,或者使用一个连接池,并使用某种互斥体保护对该池的访问(即保留或释放连接)。

        4
  •  -1
  •   Tiemen    15 年前

    MySQL Threaded Clients in C

    它声明mysql_real_connect()在默认情况下不是线程安全的。需要为线程访问编译客户端库。