MongoDB的多线程并行操作

本文探讨了在多线程环境下对MongoDB进行安全操作的最佳实践,包括为每个线程绑定独立的client对象,使用连接池提高效率,以及如何避免线程间的死锁和资源竞争。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在多线程中对MongoDB进行操作,需要确保各线程之间读写的安全性,需要为每个线程绑定独立的mongocxx::client对象。以下为官方标准例子:

Never do this:

mongocxx::instance instance{};
mongocxx::uri uri{};
mongocxx::client c{uri};
auto db1 = c["db1"];
auto db2 = c["db2"];
std::mutex db1_mtx{};
std::mutex db2_mtx{};

auto threadfunc = [](mongocxx::database& db, std::mutex& mtx) {
  mtx.lock();
  db["col"].insert_one({});
  mtx.unlock();
};

// BAD! These two databases are individually synchronized, but they are derived from the same
// client, so they can only be accessed by one thread at a time
std::thread t1([&]() { threadfunc(db1, db1_mtx); threadfunc(db2, db2_mtx); });
std::thread t2([&]() { threadfunc(db2, db2_mtx); threadfunc(db1, db1_mtx); });

t1.join();
t2.join();

A better version:

mongocxx::instance instance{};
mongocxx::uri uri{};
mongocxx::client c1{uri};
mongocxx::client c2{uri};
std::mutex c1_mtx{};
std::mutex c2_mtx{};

auto threadfunc = [](std::string dbname, mongocxx::client& client, std::mutex& mtx) {
  mtx.lock();
  client[dbname]["col"].insert_one({});
  mtx.unlock();
};

// These two clients are individually synchronized, so it is safe to share them between
// threads.
std::thread t1([&]() { threadfunc("db1", c1, c1_mtx); threadfunc("db2", c2, c2_mtx); });
std::thread t2([&]() { threadfunc("db2", c2, c2_mtx); threadfunc("db1", c1, c1_mtx); });

t1.join();
t2.join();

The best version:

(注:连接池大小可由uri中指定)

mongocxx::instance instance{};

mongocxx::pool pool{mongocxx::uri{"mongodb://localhost:27017/?minPoolSize=3&maxPoolSize=3"}};

auto threadfunc = [](mongocxx::client& client, std::string dbname) {
  auto col = client[dbname]["col"].insert_one({});
};

// Great! Using the pool allows the clients to be synchronized while sharing only one
// background monitoring thread.
std::thread t1 ([&]() {
  auto c = pool.acquire();
  threadfunc(*c, "db1");
  threadfunc(*c, "db2");
});

std::thread t2 ([&]() {
  auto c = pool.acquire();
  threadfunc(*c, "db2");
  threadfunc(*c, "db1");
});

t1.join();
t2.join();

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值