database - Berkeley DB 中的多线程应用程序

标签 database multithreading berkeley-db

我有一个简单的多线程应用程序。所有线程只会对同一个数据库进行 put 操作。但是一个线程在进行put操作之前,会先获取互斥锁增加key号,然后释放锁再进行put操作,即线程可能会同时插入不同key号的item时间。这就是我在申请中所做的。

我仍然感到困惑的是,这个简单的应用程序是否需要指定 DB_INIT_LOCK 标志或 DB_INIT_CDB 标志?我已经阅读了有关这些标志的文档。 DB_INIT_CDB 意味着多次读取/单个写入器,但是,在我的简单应用程序中,线程可以并发运行,而不是单个写入器,所以我不需要它。对于 DB_INIT_LOCK,由于线程永远不会插入具有相同键的项目,所以我不需要它,对吗?

如有错误请指正。非常感谢。

最佳答案

您正确地指出 DB_INIT_CDB 为您提供了一个多读取器、单写入器环境。这使 Berkeley DB 处于完全不同的运行模式。但是,由于您有多个 writer,因此无法使用它。

您至少需要这两个标志:

DB_INIT_LOCK:您正在围绕数据库 key 生成进行自己的锁定。但是当您将记录插入数据库时​​,Berkeley DB 将触及一些相同的内存。例如,您插入的前两条记录在数据库中将紧挨着彼此。除非它们很大,否则它们将位于内存的同一数据库“页面”上。您需要此标志来告诉 BDB 进行自己的锁定。

这就像您实现了自己的内存中多线程正在更改的二叉树一样。您必须使用某种锁定来防止线程使用不兼容的更新完全破坏树。

DB_THREAD:这个标志让 BDB 知道多个线程将使用相同的数据库环境。

您可能会发现您需要使用事务,或者至少允许 BDB 在内部使用它们。那是 DB_INIT_TXN。而且,我一直需要 DB_INIT_MPOOLDB_PRIVATE 来允许 BDB 使用 malloc() 来管理它自己的一些内存。

(顺便说一句,如果您的 key 有一个简单的增量,请考虑使用原子增量操作而不是互斥锁。如果您将 C 与 gcc 一起使用,内置的 __sync_fetch_and_add (或 __sync_add_and_fetch) 可以为你做到这一点。从 C++ 中,你可以使用 std::atomic 的后增量。)

关于database - Berkeley DB 中的多线程应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38127659/

相关文章:

java - Thread Pool实现代码中的疑问

mysql - 将 MySql 表转换为 BerkelyDB

svn - 颠覆存储库类型

c# - Oracle ODP.net 非托管 12.2 (Oracle.DataAccess.dll) 需要哪些依赖项/dll?

SQL Server - 在这里使用复合主键有什么好处?

java - 如何中断 Future,但仍然等待它完成?

python - 使用 Python 和 bsddb3 在 Berkeley DB 数据库中存储数据

c# - 基于服务的数据库和本地数据库之间的混淆

database - 哪个 ORM 框架最能处理 MVCC 数据库设计?

multithreading - 在非 JavaFX 应用程序线程上创建新的工具提示