Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在多线程环境中管理sqlite数据库 使用SQLite C++库时,可以使用 SQLITE3OPENVI2>代码>打开数据库。这将生成数据库的句柄,并设置指向该句柄的指针_C++_Multithreading_Sqlite - Fatal编程技术网

在多线程环境中管理sqlite数据库 使用SQLite C++库时,可以使用 SQLITE3OPENVI2>代码>打开数据库。这将生成数据库的句柄,并设置指向该句柄的指针

在多线程环境中管理sqlite数据库 使用SQLite C++库时,可以使用 SQLITE3OPENVI2>代码>打开数据库。这将生成数据库的句柄,并设置指向该句柄的指针,c++,multithreading,sqlite,C++,Multithreading,Sqlite,使用该指针,我可以调用sqlite3\u prepare\u v2来准备sqlite语句,然后我可以使用sqlite3\u step逐步查看查询结果 现在,我正在一个环境中工作,在这个环境中,我有几个连续创建和销毁的多线程(这是一个服务器应用程序,它生成新线程来服务传入的,可能是并发的连接)。现在,根据我的理解,我应该在每次创建新线程时通过调用sqlite3\u open\u v2为同一数据库创建新句柄。然而,这增加了大量的计算开销,因为创建到数据库的新连接可能需要一些时间,而且我需要处理很多连

使用该指针,我可以调用
sqlite3\u prepare\u v2
来准备sqlite语句,然后我可以使用
sqlite3\u step
逐步查看查询结果

现在,我正在一个环境中工作,在这个环境中,我有几个连续创建和销毁的多线程(这是一个服务器应用程序,它生成新线程来服务传入的,可能是并发的连接)。现在,根据我的理解,我应该在每次创建新线程时通过调用
sqlite3\u open\u v2
为同一数据库创建新句柄。然而,这增加了大量的计算开销,因为创建到数据库的新连接可能需要一些时间,而且我需要处理很多连接

所以我想知道是否有更有效的方法来实现这一点。例如,有没有一种方法可以将所有内容互斥以解决我的问题?我可以将我的调用互斥到我唯一拥有的连接对象:这将序列化我与数据库的通信

这样行吗?或者,即使我避免了任何形式的并发,我也不能从几个不同的线程使用同一个连接对象,这有什么原因吗

如果这可以工作,我应该序列化我对
sqlite3\u prepare\u v2
的调用,还是我对
sqlite3\u step
的第一次调用,还是我对
sqlite3\u step
的所有调用?我的意思是:当我第一次调用
step
时,每次调用
step
都会加载所有结果,或者与实际数据库文件进行通信

区别在于只对
prepare
调用进行静音,以及在完成
步骤之前锁定所有内容


这样做可行吗?我是否应该每次都创建到数据库的新连接,让sqlite处理所有的并发性,或者我是否遗漏了一些可以轻松解决问题的重要内容?

您可以让sqlite3为您处理所有这些,默认情况下应该这样做。sqlite3库应使用(empahsis mine):

SQLITE_线程安全=
此选项控制SQLite中是否包含代码,以使其能够在多线程环境中安全运行默认值为SQLITE_THREADSAFE=1,可在多线程环境中安全使用

SQL\u CONFIG\u序列化的
也应该是(强调我的):

SQLITE\u配置\u已序列化
此选项没有参数。此选项将线程模式设置为序列化。换句话说,此选项启用所有互斥体,包括数据库连接和准备语句对象上的递归互斥体在此模式下(这是使用SQLite_THREADSAFE=1编译SQLite时的默认设置)SQLite库本身将序列化对数据库连接和准备语句的访问,以便应用程序可以在不同线程中同时自由使用相同的数据库连接或相同的准备语句

但是,您也可以通过以下方式自行更改:

然后,您应该能够使用:


您还可以使用
std::mutex
来阻止对sqlite3调用的访问,但这不应该是必需的,因为sqlite3会为您处理它(但如果出于某种原因,您以不同的方式构建库,这将是可行的)。

我认为您应该检查是否调用
sqlite3\u config()
sqlite3\u initialize()之后的函数
。如果是,函数
sqlite3\u config()
将返回SQLITE\u

下面是有关sqlite3-config()API的部分解释,这些API与错误代码SQLITE\u有关

sqlite3\u config()
接口只能在库初始化之前使用调用,或在关闭之后由调用。如果在
sqlite3\u initialize()
之后和
sqlite3\u shutdown()
之前调用
sqlite3\u config()
,则它将返回SQLITE\u。但是,请注意,
sqlite3\u config()
可以作为定义的应用程序实现的一部分进行调用


来源:

我试着这么做,但我得到了一个
SQLITE\u错误。这是什么意思?对不起,我给了你一点错误!我已经更新了我的答案,以提供您需要的信息。
sqlite3_config(SQL_CONFIG_SERIALIZED);
sqlite3* pDatabase;
sqlite3_open_v2("MyDatabase.db", &pDatabase, SQLITE_OPEN_FULLMUTEX, nullptr);