c - SQLite 和安全 fork

标签 c sqlite

我有一个应用程序,其中有许多 SQLite 数据库的读取器并行执行,每个读取器都在自己的进程中。这些进程可以 fork ...并且能够在 SQLite 连接建立后执行此操作。

我想编写一个 fork 处理程序,以便当父进程 fork 时,所有 SQLite 状态都会在子进程中“刷新”...这意味着所有准备好的语句、数据库连接和其他资源都会立即更新未经清理就被丢弃。

作为一个库,SQLite 管理自己的内存和其他资源,因此理论上是可能的。

实际上,我想要做的是在 fork 时复制非 SQLite 应用程序状态,但如果程序通过 exec* 而不是 开始执行,则具有会出现的 SQLite 状态> fork

如果可能的话,我想做的是这样的:

void sqlite_refresh(void)
{
     // discard all sqlite-specific state
     // make all sqlite3_db, sqlite3_stmt &c pointers NULL
     return;
}

// call this code somewhere
pthread_atfork(
     /* prepare */ NULL,
     /* parent */  NULL,
     /* child */   sqlite_refresh
);

在 SQLite 网站上,有一些关于不使用 fork 的评论,但似乎是在假设程序员打算在 fork 后在子进程中与 SQLite 库交互的情况下编写的。

SQLite 在 its documentation 中给出了以下不祥的警告关于使用fork:

Do not open an SQLite database connection, then fork(), then try to use that database connection in the child process. All kinds of locking problems will result and you can easily end up with a corrupt database. SQLite is not designed to support that kind of behavior. Any database connection that is used in a child process must be opened in the child process, not inherited from the parent.

Do not even call sqlite3_close() on a database connection from a child process if the connection was opened in the parent. It is safe to close the underlying file descriptor, but the sqlite3_close() interface might invoke cleanup activities that will delete content out from under the parent, leading to errors and perhaps even database corruption.

上面写着here那个

Under Unix, you should not carry an open SQLite database across a fork() system call into the child process.

最佳答案

子进程不得对从父进程获取的连接/语句对象执行任何操作。这意味着您的 sqlite_refresh() 函数必须为空,或者它只是将所有指针设置为 NULL。 (这意味着内存泄漏。)

fork 时最好不要打开连接。

关于c - SQLite 和安全 fork ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50770851/

相关文章:

c - 可移植 ISR 安全数据传递

c - 来自/usr/lib/system/libsystem_platform.dylib 的段错误(作者标记为删除)

android - SQLiteDatabase 插入函数返回 -1

C++ 正确处理 sqlite3_prepare 和 sqlite3_step 错误的方法

ios - 从 SQlite 数据库中获取唯一的月-年组合

Android SQLite select * from table where name like %key% 使用准备好的语句

c - 为什么我的指针输出奇怪?

python - Python和ctype访问C全局变量结构的方法

c - 如何避免在信号处理程序中使用 printf?

php - 使用php导出sqlite表