我正在开发一个程序(notifyfs),它负责缓存目录条目并观察底层文件系统的变化。缓存存储在共享内存中,(gui)客户端可以很容易地使用缓存。
服务器(notifyfs)和客户端之间的通信可以使用套接字或通过共享内存自身,通过共享互斥锁和条件变量。
当客户端想要加载目录时,它会执行以下操作:
一个。选择一个“视图”,它是共享内存中的一个数据结构,它由一个共享互斥体、条件变量和一个小队列(数组)组成,用于与客户端通信添加/删除/更改事件。
湾。客户端用它在共享内存中找到的内容填充他/她的模型
C。向服务器发送一条消息,其中包含对视图的引用,以及它想要加载其内容的路径的指示。这可能是一个路径,但如果可能的话是父条目。
d。服务器接收消息(进行一些检查),在目录上设置监视,并同步目录。当目录尚未在缓存中时,这意味着它检测到的每个条目都存储在缓存中。这样做时,它会向视图(共享内存中的数据)发出信号,添加一个条目,并将此事件存储在数组/队列中。
e. gui 客户端有一个特殊的线程,它使用 pthread_cond_wait 调用不断地在共享内存中监视此视图以进行更改。这个线程是一个特殊的io线程,可以发送三个信号:entry added、entry remove和entry changed。它从数组队列中读取的正确参数:对条目的引用以及操作是什么。这三个信号连接到我的模型中的三个插槽,该模型基于 QStandardItemModel。
这完美地工作。它非常快。在测试它时,我有很多调试输出。在删除这些以在没有这个额外缓慢的 io 的情况下对其进行测试后,看起来 QTreeView 无法赶上这些变化。当加载一个目录时,它会加载它的三分之二,而当要加载另一个目录时,它会越来越少。
我已经使用 Qt::QueuedConnection 将来自特殊线程的不同信号连接到模型。
在某一行添加一行是使用 insertRow(row, list) 调用完成的,其中 row 当然是行,而 list 是项目的 QList。
我一直在寻找这个问题一段时间,发现所有的变化都被特殊的 io 线程检测到,并且模型接收到了信号。仅以某种方式未收到到 QTreeView 的信号。我一直在想,我是否必须将模型信号和树视图的接收槽之间的通信也设置为“Qt::QueuedConnection”?也许还有别的?