c++ - 这段代码对 C++ 是线程安全的吗

标签 c++ multithreading

我读过有关双重检查的文章,在任意 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/

相关文章:

c++ - 修改const shared_ptr&传递的数据可以吗?

c++ - 为什么流输出中的 < 而不是 << 仍然可以编译?

c++ - 长 C++ 模板类型的 doxygen 换行符

c++ - 奇怪的未声明的变量编译器错误

c++ - 仅当前一个线程完成时才创建一个新线程

c# - 计算功能限制的最佳方法是什么?

c++ - 处理消息太慢,导致 UI 不稳定、无响应 - 如何使用多线程来缓解这种情况?

c# - 多个 View 共享相同的数据与多个线程之间的双向数据绑定(bind)

multithreading - 如何并行运行bash脚本的各个部分

c# - Thread.Start() 与 ThreadPool.QueueUserWorkItem()