我读过有关双重检查的文章,在任意 CPU 上使用 C++ 可能不安全。我不太确定我的代码是否绝对安全。 Database类代表数据库文件,连接是在需要的时候动态创建的。 Database::GetConnection 可以同时从不同线程调用。如果代码不是绝对安全的,我该如何修改代码。谢谢。
#include <mutex>
#include "sqlite3.h"
class Connection
{
private:
sqlite3* _handle;
std::string _path;
public:
Connection(const std::string& path) : _path(path) {
sqlite3_open(_path.c_str(), &_handle);
// some other initialization work..
}
}
class Database
{
private:
typedef enum
{
Void,
Connected,
// some other status...
} Status;
std::string _path;
std::mutex _mutex;
Status _status;
Connection* _connection;
void OpenDatabase()
{
_connection = new Connection(_path);
_status = Connected;
}
public:
Connection* GetConnection()
{
if (_status == Connected)
return _connection;
std::lock_guard<std::mutex> guard(_mutex);
if (_status != Connected)
OpenDatabase();
return _connection;
}
public:
Database(const std::string& path) : _path(path), _status(Void) {};
};
最佳答案
For efficiency ... is safe enough
您正在处理数据库,效率没有实际意义,足够安全取决于您
足够 表示允许的不确定性水平。 你同意吗?
如果有 0.001% 的可能性不 足够安全,会发生什么?软件会崩溃吗?硬件会爆炸吗?鸟会翻过来从天上掉下来吗?
如果您的 OpenDatabase
函数在您的 Database
类中的其他任何地方都被锁定,那么删除第一个检查并保留您的 GetConnection
函数有什么问题这样:
Connection* GetConnection()
{
std::lock_guard<std::mutex> guard(_mutex);
if (_status != Connected)
OpenDatabase();
return _connection;
}
你正在处理一个数据库,所以你的 CPU 需要几毫秒来创建和存储 std::lock_guard
并锁定/解锁 _mutex
对象然后执行一个简单的 bool 检查,与为数据库建立连接和事务状态可能需要的 100 毫秒相比微不足道。
拯救鸟类。
关于c++ - 这段代码对 C++ 是线程安全的吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40755296/