02-09-2017 10:47 PM
①データを収集し、解析、結果をcsvに連続で書き込むソフト
②結果が書き込まれたcsvファイルを一定間隔でサーバーにコピーするソフト
の2つを一つのPCで動かしています。
①の結果を連続で書き込む際のcsvファイルは収録数が増えるたびに行数が追加されていき、連続で動き続けます。
そこで現在①のデータ書き込みと、②のコピーのタイミングが一致し、csvのアクセスが競合した時に書き込みエラーが発生し、①のデータに抜けもれが発生してしまいます。
これを回避するために②のcsvファイルをサーバーにコピーする際に読み取り専用で開き、コピーできないかと考えていますが方法を教えていただけないでしょうか?
もしくは、別のアイディアがあれば教えていただけないでしょうか。
よろしくお願いします。
02-11-2017 01:56 AM - 編集済み 02-11-2017 01:58 AM
①②はどちらもviで、1台のPCのLabVIEW上で同時に走っている2つのvi、でしょうか?
②のコピーは、「ファイルから読み込み」を行って、それをサーバの別ファイルに「ファイルに書き込み」を行っていますか? それとも、上級ファイル関数の「コピー」を使っていますか?(もし前者でやっている場合は、後者を使うと多少マシかも知れませんが絶対ではないかも知れません。ネットワーク越しだとコピーも時間かかるかも知れないので、ローカルにさっとコピーして、別途それをサーバにさらにコピーする、という方法も)
通常、このように同一ファイルに対するアクセスの競合を防ぐ場合は「同期」を使うのが良く、今回のだと同期の「セマフォ」が良いですかね。
LabVIEW上で動く2つのviであれば、セマフォの名前(何でも良い)を決めておいて、どちらのviからも同じ名前でセマフォを生成します(同じ名前なら同じセマフォになる)。2つのviをA(測定書き込み)・B(サーバへコピー)とすると、Aがファイルにアクセスしようとした時、Aはまずセマフォを要求する関数を呼びセマフォを獲得してからファイルにアクセスします。その間、後からBがファイルにアクセスしようとしてセマフォを要求しても、セマフォが出払っているので一旦待たされます。そしてAはアクセスを終えたらセマフォを返す関数を呼びます。すると、待たされていたBはセマフォをもらえて処理が返ってくるので、ファイルにアクセスできます(この間Bがセマフォを持っているので、次にAがファイルにアクセスしようとした時Bがまだセマフォを持っていたら、Bのアクセスが終わってセマフォを返すまで待たされますし、既にBがセマフォを返していたら、Aはすぐセマフォを受け取れます)。
測定書き込みをするAが待たされるのは可能な限り短くしたいでしょうから、Bの処理は、セマフォをもらったら「ファイルコピー関数」だけ呼び出してローカルにコピーをしてすぐセマフォを返すのがいいかなと思います。あとは、Bはローカルにコピーしたのをサーバにコピーして、ローカルのコピーを削除します。
02-14-2017 06:22 PM
M.Shiraishi 様
返信頂きありがとうございます。
①、②はどちらもviで同一のPC上で同時に走っています。
コピーには上級関数の「コピー」を使用していたのですが、ネット枠環境等にもより、速度が遅くなった場合にエラーが発生していました。
当方、セフォマに関しては知識が乏しく、今回アドバイスを頂いた内容でセフォマの習得も兼ねて検討してみたいと思います。
アドバイスありがとうございました。
02-15-2017 07:21 AM
>>コピーには上級関数の「コピー」を使用していたのですが、
>>ネット枠環境等にもより、速度が遅くなった場合に
なるほど、そうしますと、「コピー」関数でも遅延すると発生するとのことで、
1つには、オリジナルのコピーはまずローカルにさっと行うことで
ネットワーク遅延を受けないようにすることが考えられますが、
(ネットワーク越しのコピーはローカルのコピーから孫コピー)
競合の頻度は下がっても、絶対にゼロ、とはならないので、
前述の通り、セマフォ等を使ってうまく回避できたら良いと思います。
セマフォも、なるべく測定書き込み側viが待たされないよう、
コピー側viはローカルコピーだけでさっとセマフォを返せるように・・でしょうかね。
セマフォは、うまく説明しづらい部分はありますが、
サンプルプログラムないしセマフォの関数のヘルプで、ある程度は
つかめるかなと思います。