2008-09-19 5 views
5

私はDelphiで書かれたコマンドラインツールを持っています。このツールは、ノードをXMLファイルに挿入してすぐに終了することです。私はツールのいくつかのインスタンスを同時に実行し、ノードを同じXM​​Lに挿入することを可能にする必要があります。Delphiを使用して、EXEの複数のインスタンスからXMLファイルへの同時入出力アクセスを管理する方法。

この目的を達成するために、単純なファイル「mutex」を導入しました。このツールは、XMLに書き込む前に1つの一時ファイルを作成し、終了後に一時ファイルを削除します。したがって、別のインスタンスが実行されると、この一時ファイルの存在を確認し、削除されるまで待機します。その後、再び一時ファイルを作成し、XMLに書き込み、一時ファイルを削除します。

問題は、2-3のインスタンスが同時にXMLファイルに書き込もうとしたときにうまく動作することです。より多くのインスタンスがある場合、それらのインスタンスのいくつかは永遠に待機し、ノードをXMLに追加することはありません。

同時に実行してXMLに書き込む多数のインスタンスで動作させるより良い方法がありますか?

+0

これまでの回答はありがとうございます。まずコード内に論理的な誤りがあり、私はそれを修正しましたが、私が使用する方法はまだ良くありません。 次の小規模なツールで私は続行します。そして、ここで更新を書いて、最も適切な答えを受け入れます。 –

+0

クライアント/サーバーソリューションのように見えます。 –

答えて

6

名前付きセマフォまたはミューテックスは、単一のマシン上でこれを行うことができます。例えばSyncObjsからTMutexを取得し、name引数を取るコンストラクタの1つを使用します。すべてのアプリケーションで同じ名前を使用すると、同じカーネルミューテックスで同期されます。 TMutexを使用します。取得してアクセスし、TMutex.Releaseを実行したらtry/finallyブロックで保護します。

InitialOwner引数を持つTMutex.Createオーバーロードを使用しますが、これに対してFalseを指定します(もちろん、ミューテックスをすぐに取得しない場合)。このオーバーロードは、シーンの背後にあるCreateMutexを呼び出します。詳細はSyncObjsのソースとCreateMutexのドキュメントを参照してください。

+0

最後に私はこのプロジェクトに再びループしました。ミューテックスが問題を解決しました。 10x :) –

4

1 - そのファイルを見るためにシンプルなアプリを書いて、XMLファイルへの変更

3を適用する - 保留中の変更を記録するファイル(それはキューのように動作します)

2を設定します - 現在のコマンドラインツールを変更して、変更要求を「保留中の変更」ファイルに追加します。

最終的なXMLファイルに1つのアプリケーションしかアクセスできません。

+0

おそらくディレクトリを簡単に作成できます必要な変更が個別のファイルとして追加されます。追加するファイルがないので、ドロップして実行してください。 – mj2008

+0

私はその考えが好きです – JosephStyons

+0

しかし、すべてのインスタンスは同じ保留中の変更ファイルに再度書き込む必要があります。これは問題を別のファイルに転送するだけです。ディレクトリのアイデアは実際にはうまくいくでしょう。 –

2

TXMLDocumentはすでに複数のインスタンスが同じファイルに同時に書き込むのを防ぎます。だからあなたの質問が本当に意味することは、 "は、私がを読んでいる間に、他のインスタンスが書類に書き込むのを防ぐために、どのようにXML文書を開くことができるのかを推測しています。同じことをするインスタンス? "

この場合、ファイルのオープンとクローズは、TXMLDocumentで許可するのではなく、自分で処理する必要があります。 LoadFromFileではなくTFileStreamを使用して、排他的な読み書きロックとXMLDocument.LoadFromStreamでファイルを開きます。 stream.Positionを0にリセットした後、SaveToStreamでドキュメントを保存します。終了したらストリームを閉じるためにtry/finallyを使用します。排他的にファイルをロックしているので、一時ファイルやその他の種類のミューテックスは必要ありません。

明らかに、別のインスタンスが現在読み書き中の場合、ファイルを開くことができない可能性があります。したがって、これを処理して後で再試行する必要があります。

1

ノードを追加する必要があるたびに、ドキュメント全体を再読み込みして再解析する必要があります。 XML文書のサイズと保存するデータによっては、データを転送する最も効率的な方法ではない可能性があります。

別ファイルへの書き込みのアプローチは面白い解決策です。あなたの「複数インスタンス」アプリケーションで一意のXMLファイルを作成し、それらをFindFirstループを使用して別のプログラムでマスタードキュメントに読み込む方法があります。そうすれば、既存のプログラムに大きな変更を加えることなく、XML構造をそのまま維持できます。

0

this answerから:

Windows上であなたは両方のプログラムを制御することができれば、これは可能です。 LockFileEx。読み取りの場合は、ロックファイルの共有ロックを開きます。書き込みの場合、 はロックファイルに排他ロックをオープンします。 Windowsではロックが奇妙なので、 だから、これには別のロックファイルを使うことをお勧めします。

(それだけで複数のインスタンスで実行して、同じプログラムである時に「どちらのプログラムのDOSがあなたのケースには適用されません。)私はこの答えを見つけた方法

サイドノート/:Javaロギングライブラリlogback用途プラットフォーム固有のファイルロックAPI(NIO経由)は、複数のプロセスが同じファイルに壊れずにログインできる「prudent mode」を実装しています。これは、DelphiのRTLファイル操作では不可能です。

関連する問題