MongoDB C ++:mongocxx :: pool线程安全吗?

时间:2017-01-04 14:22:42

标签: c++ multithreading mongodb mongo-cxx-driver

获取连接时是否必须手动锁定mongocxx :: pool?

这样安全吗? (从Mongo网站复制的例子)

mongocxx::instance instance{};
mongocxx::pool pool {mongocxx::uri{}};

using mongocxx::pool::entry = std::unique_ptr<client, std::function<void (client*)>>

auto threadfunc = [](mongocxx::client &client, stdx::string_view dbname) {
    client[dbname]["col"].insert({});
}
// don't even bother sharing clients. Just give each thread its own,
std::thread([]() {
    // pool.acquire() returns a mongo::pool::entry type
    mongocxx::client *c= pool.acquire().get();
    threadfunc(*c, "db1");
    threadfunc(*c, "db2");
});

std::thread([]() {
    mongocxx::client *c = pool.acquire().get();;
    threadfunc(*c, "db2");
    threadfunc(*c, "db1");
});

1 个答案:

答案 0 :(得分:5)

是的,mongocxx::pool是线程安全的。您可以从多个线程同时访问它。但是,从池返回的单个mongocxx::client对象是线程安全的,collectiondatabase等从属对象也不是从{{1}获取的 - 你不能在线程之间共享它们。

另请注意,您的示例(不是从网站逐字复制而是从其中一个示例中修改)包含严重的编程错误。

这一行:

client

将获取一个池条目,然后从中提取一个裸指针。但是,池条目将在语句结束时销毁,导致基础 mongocxx::client *c= pool.acquire().get(); 对象返回到池中,允许另一个线程在您继续使用它时可能会将其取出。

你应该把它写成:

client

这样,每个线程都会保留池条目,直到它完成使用它为止,此时mongocxx::instance instance{}; mongocxx::pool pool {mongocxx::uri{}}; auto threadfunc = [](mongocxx::client &client, stdx::string_view dbname) { client[dbname]["col"].insert({}); } // don't even bother sharing clients. Just give each thread its own, std::thread([]() { // pool.acquire() returns a mongo::pool::entry type auto c = pool.acquire(); threadfunc(*c, "db1"); threadfunc(*c, "db2"); }); std::thread([]() { auto c = pool.acquire(); threadfunc(*c, "db2"); threadfunc(*c, "db1"); }); 中的unique_ptr被销毁时会自动返回。