Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ssis/2.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
Python 我如何将在不同进程中进行的SQLite数据库更改通知进程?_Python_Sqlite_Notifications - Fatal编程技术网

Python 我如何将在不同进程中进行的SQLite数据库更改通知进程?

Python 我如何将在不同进程中进行的SQLite数据库更改通知进程?,python,sqlite,notifications,Python,Sqlite,Notifications,假设我有两个或多个处理SQLite数据库的进程——一个“播放器”进程和许多“编辑器”进程 “player”进程读取数据库并更新一个视图——在我的例子中,它将是一个波形,根据数据库中存储的事件混合到声卡中 “编辑器”进程是该数据库的任何编辑器:它不断更改数据库 现在我希望播放器能够快速反映编辑更改 我知道SQLite提供了钩子来跟踪同一进程内的数据库更改,但似乎没有多少关于如何使用多个进程来实现这一点的信息 我可以不断轮询数据库,比较记录和触发事件,但这似乎效率很低,尤其是当数据库增长到很大的规模

假设我有两个或多个处理SQLite数据库的进程——一个“播放器”进程和许多“编辑器”进程

“player”进程读取数据库并更新一个视图——在我的例子中,它将是一个波形,根据数据库中存储的事件混合到声卡中

“编辑器”进程是该数据库的任何编辑器:它不断更改数据库

现在我希望播放器能够快速反映编辑更改

我知道SQLite提供了钩子来跟踪同一进程内的数据库更改,但似乎没有多少关于如何使用多个进程来实现这一点的信息

我可以不断轮询数据库,比较记录和触发事件,但这似乎效率很低,尤其是当数据库增长到很大的规模时


我正在考虑使用日志表和触发器,但我想知道是否有更简单的方法。

只需打开两个进程之间的套接字,让编辑器告诉所有玩家有关更新的信息。

编辑:我正在同一台机器上分析进程

我认为有两种方式:

  • 轮询(如您所提到的),但将其保留为单个值(就像一个只保留其他表的LastUpdateTime的表)

  • 使用目标平台上可用的任何进程间通信。这可能是Windows中的事件(例如,在C#(我不知道在Python中是什么)、ManualResetEvent、AutoResetEvent或互斥体(如果您想在每个进程中牺牲一个等待线程),也可能是Linux中的事件


关系数据库不是您的最佳首选

为什么?

您希望所有编辑器将更改传递给播放机

实际上,您的播放器是所有这些编辑器的服务器。您的播放器需要多个打开的连接。它必须侦听所有这些连接以获取更改。它必须显示这些更改

如果更改非常大,您可以使用混合解决方案,其中编辑器保留更改并通知播放器

无论哪种方式,编辑都必须通知他们的玩家他们有更改。这比玩家试图发现数据库中的更改要简单得多


更好的设计是一个服务器,它接受来自编辑器的消息,将它们持久化,并通知播放器。该服务器既不是编辑器也不是播放器,只是一个确保所有消息都得到处理的代理。它接受来自编辑和玩家的连接。它管理数据库

有两种实现。服务器就是播放器。服务器和播放器是分开的。服务器的设计没有改变,只改变了协议。当服务器是播放器时,服务器直接调用播放器对象。当服务器与播放机分离时,服务器将写入播放机的套接字

当播放器是服务器的一部分时,当从编辑器收到消息时,将直接调用播放器对象。当播放器分离时,一个小型读取器从套接字收集消息并调用播放器对象

播放器连接到服务器,然后等待信息流。这可以是从编辑器输入的,也可以是对服务器保存在数据库中的数据的引用

如果您的消息流量足够小,因此网络延迟不是问题,则编辑器会将所有数据发送到服务器/播放器。如果消息流量过大,则编辑器将写入数据库并向服务器/播放机发送仅包含数据库FK的消息


请在您的问题中澄清“如果编辑在通知时崩溃,则播放器将永远处于混乱状态”


这听起来像是一个糟糕的播放器服务设计。它不可能是“永久性的混乱”,除非它没有从不同的编辑那里得到状态。如果它从编辑器中获得状态(但是试图试图镜像该状态),那么你应该考虑一个设计,玩家只需从编辑器中获得状态,就不会“永久混乱”。

< P>如果它在同一台机器上,最简单的方法就是命名管道,“播放器”带有块读()和“编辑器”。每当他们修改DB时,在管道中放置一个令牌。

有多少个编辑器进程(为什么是进程?),您希望多久更新一次?这听起来不是一个好的设计,尤其是没有考虑到sqlite真的对多个并发访问数据库不太满意


如果多个进程有意义,并且您想要持久化,那么让编辑器通过套接字、管道、共享内存等通知您的播放器,然后让播放器(也称为服务器进程)执行持久化可能会更明智。

我想在这种情况下,我会创建一个进程来管理数据库读/写

每个想要对数据库进行一些修改的编辑器都会调用这个过程,无论是通过IPC还是网络,或者是任何方法

然后,该过程可以将数据库中的更改通知播放器。当玩家想要检索一些数据时,应该向管理数据库的进程请求它想要的数据。(或者db进程在通知更改时告诉它需要什么,因此不需要来自播放器的请求)

这样做的好处是只有一个进程访问SQLite DB,因此数据库上没有锁定或并发问题。

SQLite有一个函数,可以实现您想要的功能

SQLite C接口

数据更改通知回调

sqlite3\u update\u hook()
接口向 由要调用的第一个参数标识的数据库连接 每当在rowid表中更新、插入或删除行时。任何 由上一次调用此函数为同一数据库设置的回调 连接被覆盖

不幸的是,它不是前男友
void *sqlite3_update_hook(
    sqlite3*,
    void(*)(void *,int ,char const *,char const *,sqlite3_int64),
    void*
);