MongoDB C++:mongocxx::pool 线程安全吗?
MongoDB C++: Is mongocxx::pool thread safe?
获取连接时是否必须手动锁定 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");
});
是的,mongocxx::pool
是线程安全的。您可以从多个线程同时访问它。但是,从池中返回的单个 mongocxx::client
对象 不是 线程安全的,从属对象 collection
或 database
也不是从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");
});
这样,每个线程都会保留池条目,直到它使用完它,此时它会在 c
中的 unique_ptr
被销毁时自动返回。
获取连接时是否必须手动锁定 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");
});
是的,mongocxx::pool
是线程安全的。您可以从多个线程同时访问它。但是,从池中返回的单个 mongocxx::client
对象 不是 线程安全的,从属对象 collection
或 database
也不是从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");
});
这样,每个线程都会保留池条目,直到它使用完它,此时它会在 c
中的 unique_ptr
被销毁时自动返回。