我在Windows应用程序中使用SQLite3。我有源代码(所谓的SQLite合并)。
有时我必须执行大量查询。也就是说,我在准备好的语句上调用sqlite3_step
,并且需要花费很多时间才能完成(由于I / O负载很大)。
我想知道是否有可能中止这样的电话。如果能够在同一个线程中的中进行一些后台处理,我也会很高兴(因为大部分时间花在等待I / O完成上)
我想过自己修改SQLite代码。在最简单的场景中,我可以在每次调用ReadFile
/ WriteFile
之前检查一些条件(例如中止事件句柄),并适当地返回错误代码。并且为了允许后台处理,应该以重叠模式打开文件(这将启用异步ReadFile
/ WriteFile
)。
在某些情况下,WriteFile
的中断是否有可能使数据库处于不一致状态,即使启用了日志?我想不是,因为日志文件的整个想法是为任何类型的错误做好准备。但是我希望听到更多关于此的意见。
另外,有人试过类似的东西吗?
提前致谢。
修改
感谢ereOn。我不知道sqlite3_interrupt
的存在。这可能回答了我的问题。
现在,对于所有想知道如何(以及为什么)在同一个线程中的I / O期间进行一些后台处理的人来说。
不幸的是,很多人都不熟悉所谓的“重叠I / O”。
http://en.wikipedia.org/wiki/Overlapped_I/O
使用它会发出I / O操作异步,并且调用线程未被阻止。然后使用其中一个完成机制接收I / O完成状态:waitable事件,排队到APC的新例程或完成端口。
使用这种技术,不必创建额外的线程。实际上,创建线程的唯一真正的合法性是当你的瓶颈是计算时间(即CPU负载),并且机器有多个CPU(或核心)时。
创建一个线程只是为了让它在大多数时间被操作系统阻止 - 这没有意义。这导致了OS资源的不合理浪费,使程序复杂化(需要同步等)。
不幸的是,并非所有的库/ API都允许异步操作模式,因此创建额外的线程必然是邪恶的。
EDIT2:
我已经找到了解决方案,但是已经找到了解决方案。
对于所有那些坚持认为在“等待”I / O完成使用重叠I / O时“背景”不值得做的人。我不同意,我认为没有必要争论这个问题。至少这与主题无关。
我是一名Windows程序员(您可能已经注意到了),我在各种多任务处理方面拥有丰富的经验。另外,我也是一名司机作家,所以我也知道“幕后”的工作原理。
我知道创建多个线程以“并行”执行多项操作是一种“常见做法”。但这并不意味着这是一个很好的做法。请允许我不要遵循“惯例”。
答案 0 :(得分:3)
我不明白为什么你希望中断来自相同的线程,我甚至不明白这是怎么可能的:如果当前线程被阻塞,等待一些IO ,你不能执行任何其他代码。 (是的,这就是“阻止”的意思)
也许如果你给我们更多关于你为什么想要这个的提示,我们可能会进一步提供帮助。
通常,我使用sqlite3_interrupt()
来取消通话。但显然,这涉及到调用是从另一个线程进行的。
答案 1 :(得分:1)
默认情况下,SQLite is threadsafe。对我来说,最简单的事情就是在后台线程上启动Sqlite命令,并让SQLite进行必要的锁定以使其工作。
从您的角度来看,sqlite调用看起来像是I / O的异步位,您可以继续对此线程进行正常处理,例如:使用包括可中断睡眠和一些偶尔背景处理的循环(例如,更新活跃度指示符)。当SQLite语句完成时,后台线程应该设置一个状态变量来指示这一点,唤醒主线程(如果需要),然后终止。