1

私は、ディレクトリエントリのキャッシュと、基になるファイルシステムの変更を監視するプログラム (notifyfs) に取り組んでいます。キャッシュは共有メモリに格納され、(gui) クライアントはキャッシュを非常に簡単に利用できます。

サーバー (notifyfs) とクライアントの間の通信は、ミューテックスと条件変数を共有することにより、ソケットまたは共有メモリを介して行うことができます。

クライアントがディレクトリをロードする場合、クライアントは次のことを行います。

を。クライアントと追加/削除/変更イベントを通信するために、共有ミューテックス、条件変数、および小さなキュー (配列) で構成される共有メモリ内のデータ構造体である「ビュー」を選択します。

b. クライアントは、共有メモリで既に見つけたものをモデルに取り込みます

c. ビューへの参照と、コンテンツをロードするパスへの指示を含むメッセージをサーバーに送信します。これはパスかもしれませんが、可能であれば親エントリです。

d. サーバーはメッセージを受信し (いくつかのチェックを行います)、ディレクトリにウォッチを設定し、ディレクトリを同期します。ディレクトリがまだキャッシュにない場合、これは、検出されたすべてのエントリがキャッシュに格納されていることを意味します。その際、ビュー (共有メモリ内のデータ) にエントリが追加されたことを通知し、このイベントを配列/キューに格納します。

e. GUI クライアントには、pthread_cond_wait 呼び出しを使用して変更がないか共有メモリ内でこのビューを常に監視する特別なスレッドがあります。このスレッドは特別な io スレッドで、エントリの追加、エントリの削除、エントリの変更の 3 つのシグナルを送信できます。配列キューから読み取る正しいパラメータ: エントリへの参照とアクションの内容。これらの 3 つのシグナルは、QStandardItemModel に基づく私のモデルの 3 つのスロットに接続されています。

これは完全に機能します。とても速いです。テストすると、多くのデバッグ出力が得られました。これらを削除して、この余分な遅い io なしでテストした後、QTreeView が変更に追いつかないようです。ディレクトリをロードすると、その 3 分の 2 がロードされ、別のディレクトリをロードしようとすると、これはますます少なくなります。

Qt::QueuedConnection を使用して、特別なスレッドからモデルにさまざまなシグナルを接続しました。

特定の行に行を追加するには、insertRow(row, list) 呼び出しを使用します。row はもちろん行であり、list は項目の QList です。

私はしばらくの間、この問題を調べていましたが、すべての変更が特別な io スレッドによって検出され、シグナルがモデルによって受信されていることがわかりました。QTreeViewへのシグナルだけがなぜか受信されていません。モデル信号とツリービューの受信スロットの間の通信も「Qt::QueuedConnection」に設定する必要がありますか? 多分何か他のもの?

4

1 に答える 1

0

反応で提案されたのは、モデルを特別なスレッドに入れることでした。これは魅力的でしたが、これを解決する正しい方法ではありません。モデルとビューは同じスレッドにある必要があります。

この問題は、特別な io スレッドによってモデルにデータを提供する際にできる限りのことを行うことで解決しました。モデルを作成するいくつかの関数をこの特別な io に移動し、標準呼び出しを使用して行を挿入または削除しました。それはうまくいきました。

提案してくださった皆様、

ステフ・ボン

于 2014-01-21T12:39:07.143 に答える