我的应用程序在多个线程中运行。最多四个线程需要访问我的 sqlite3 数据库。为了实现这一点,我决定在单独的线程中运行数据库。在这个线程中,我有一个队列(只是一个字符串向量)。该队列通过来自其他四个工作线程的管道填充。在时间限制或最大值之后。我的队列中的元素数量我执行它。
这是一个可接受的解决方案吗?或者有人有更好的吗?
我的应用程序在多个线程中运行。最多四个线程需要访问我的 sqlite3 数据库。为了实现这一点,我决定在单独的线程中运行数据库。在这个线程中,我有一个队列(只是一个字符串向量)。该队列通过来自其他四个工作线程的管道填充。在时间限制或最大值之后。我的队列中的元素数量我执行它。
这是一个可接受的解决方案吗?或者有人有更好的吗?
SQLite 完全支持多线程。通过实施您自己的管理系统,您可以提高应用程序的性能和响应能力,但也有可能……您不会。
您需要了解的有关 sqlite 多线程的所有信息都在sqlite 线程安全文档中。我建议您考虑该文件中的信息并做出谨慎的决定。
如果您决定制作自己的解决方案,则可以使用上述文档中的信息来禁用不必要的 sqlite 内部同步。
旁注:这个问题/答案中有一些有用的信息:如何在多线程应用程序中使用 SQLite?
处理消息队列的一种常见方法是实际上有两个队列,一个用于发送方添加消息,一个用于回复。然后,不是在队列中使用简单的字符串,而是有一个结构,其中包含数据(在您的情况下为字符串)和添加回复的队列,也许还有某种标识符来知道回复的消息是什么。
随着队列数量的增加,这是一些额外的内存开销,但考虑到该方案在 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;