【问题标题】:SQLite3 Multithreading in C++ (linux)C++ 中的 SQLite3 多线程(Linux)
【发布时间】:2013-07-08 00:54:12
【问题描述】:

我的应用程序在多个线程中运行。最多四个线程需要访问我的 sqlite3 数据库。 为了实现这一点,我决定在单独的线程中运行数据库。 在这个线程中,我有一个队列(只是一个字符串向量)。该队列通过来自其他四个工作线程的管道填充。在时间限制或最大值之后。我执行它的队列中的元素数。

这是一个可接受的解决方案吗?或者谁有更好的?

【问题讨论】:

  • 有一个消息队列来在线程之间进行通信是很常见的,但为什么会有超时或任何形式的等待呢?如果请求线程想要尽快得到答案怎么办?另外,您如何跟踪哪条消息来自哪个线程,以便将结果发回?
  • 如果对数据库的所有请求都是插入|删除|更新 - 没关系(如果不提及关机时的数据丢失)。但是,如果工作线程将等待结果 - 我同意@Joachim Pileborg,则不需要超时。
  • @JoachimPileborg 我每 2 或 3 秒通过工作线程获取一个要插入的值。如果我立即写入这些值,则磁盘上有很多 I/O。如果我丢失了一些值(1 分钟是我的超时),那还不错。但另一件事,如何识别线程以获得可能的结果,我没有想到这个:/ 现在我想不出一个解决方案。能否推荐一些东西或者有一个共同的解决方案?
  • 阅读本文sqlite.org/threadsafe.html 您可以使用 1 个线程来批量写入数据库,就像您已经做的那样,每个工作人员有 1 个与数据库的连接,仅用于选择。
  • @GreenScape 感谢您的链接。如果我理解正确,我可以像这样使用 SQLITE_OPEN_FULLMUTEX 标志:sqlite3_open_v2(Path.c_str(), &DatabaseConnection, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX, NULL); 我不需要检查我是否已经插入了一些东西?对于其他线程,我会使用 SQLITE_OPEN_READONLYFULLÖMUTEX 标志?

标签: c++ linux multithreading sqlite


【解决方案1】:

SQLite 完全支持多线程。通过实施您自己的管理系统,您可以提高应用程序的性能和响应能力,但也有可能......您不会。

您需要了解的有关 sqlite 多线程的所有信息都在 sqlite threadsafe documentation 中。我建议您考虑该文档中的信息并做出谨慎的决定。

如果您决定制作自己的解决方案,则可以使用上述文档中的信息来禁用不必要的 sqlite 内部同步。

旁注:这个问题/答案中有一些有用的信息:How to use SQLite in a multi-threaded application?

【讨论】:

  • 这个答案是正确的。我会注意到,许多与我共事过的程序员对“多线程”模式和“序列化”模式的名称感到困惑。 OP 几乎肯定想要 serialized 模式(本质上将数据库连接变成monitor。)
【解决方案2】:

处理消息队列的一种常用方法是实际上有 两个 队列,一个用于发送者添加消息,一个用于回复。然后,您不必在队列中使用简单的字符串,而是有一个结构,其中包含数据(在您的情况下为字符串)和添加回复的队列,也许还有某种标识符来知道回复是针对什么消息的。

随着队列数量的增加,这是一些额外的内存开销,但考虑到这个方案在 1980 年代中期在只有 512 kb RAM(甚至更少)的计算机上使用,可以得出结论,开销不是很大。


至于实现,您可以创建一个简单的类来包装大部分功能,如果您希望不同的队列能够接收不同的数据,甚至可以将其设为模板类。

可能是这样的:

template<typename Td>
class message_queue
{
public:
    static const message_queue<Td> none{};

    // Post a message to the queue, with an optional reply queue
    void post(const Td& data, message_queue<Td>& reply_queue = none);

    // Get the first message from the queue
    // The second member of the pair is an optional message queue
    // where the reply is posted, it's `none` if no reply needed
    std::pair<Td, message_queue<Td>> get();

    // Wait for a message to arrive in the queue
    void wait() const;

private:
    // The actual message queue
    std::queue<std::pair<Td, message_queue<Td>> queue;
}

上面的类可以这样使用:

message_queue<std::string> sql_queue;

// ...

message_queue<std::string> reply_queue;
sql_queue.post("SELECT * FROM some_table", reply_queue);
reply_queue.wait();
std::string data = reply_queue.get().first;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-04
    • 1970-01-01
    • 2014-10-10
    • 1970-01-01
    • 2011-11-02
    • 2017-03-14
    • 1970-01-01
    相关资源
    最近更新 更多