排他処理についてのアドバイス

このQ&Aのポイント
  • ファイルのサイズが指定のサイズに達したときに、バックアップファイルとしてリネームし、新たにファイルを作成する処理があります。
  • 複数プロセスが同時に動作することがあり、排他がかかっていないため、複数プロセスでファイルサイズが指定のサイズをオーバーしたと判断し、リネーム処理が行われ、.bakファイルも小さなファイルになってしまう事が発生しました。
  • ファイルサイズがオーバーしたときにoverflg用のファイルを作成し、そのファイルの存在によって他のプロセスの動作を制御する方法を検討することをおすすめします。
回答を見る
  • ベストアンサー

排他処理について

あるシステムの、(CGIアプリケーションの)ログファイルの機能ですが、 ログのサイズが指定のサイズに達したとき、 バックアップファイルとしてリネームし、また新たにファイルを作成する...という処理があります。 (1)ファイルのサイズは CFile::GetStatus( FileName,fs ) で、 で、fs.m_size を取得しています。 (2)fs.m_size >= (指定のサイズ)になったときに 拡張子を .bakに切り替え(rename)ています。 ・・・ということで、同じ処理で2つのログファイルができ、.bakは指定のファイルサイズ程度で 残っているはずだったのですが。。。 複数プロセスが同時に動くことがあり、排他がかかっていないため、 複数プロセスで、ファイルサイズが指定のサイズをオーバーしたと判断し、 続けて(!?)リネーム処理が行われ、 .bakファイルも小さなファイルになってしまう事が発生しました。 これを防ぐには、排他が不可欠とはわかるのですが システムに一番影響なく、訂正するにはどのような方法があるか アドバイスしていただけないでしょうか。 かなりアクセスの多いシステムなのであまり、重たくなるような修正はできないのです。 ファイルサイズがオーバーしたときに overflg用のファイルを作成しておき、 ・そのファイルがあったら他のプロセスは何もしないで普通に書き込む  (書き込む時には排他がかかっています) ・そのファイルが無かったら、普通にファイルに書き込む  (ファイルサイズは多少オーバーしても問題はありません) ・renameが終わったら、そのoverflg用ファイルを削除する のようなことを考えたのですが、実用的でしょうか? よろしくお願いします。

  • jg1wjz
  • お礼率91% (148/162)

質問者が選んだベストアンサー

  • ベストアンサー
  • notnot
  • ベストアンサー率47% (4846/10257)
回答No.1

ファイルサイズがオーバーしたときに、overflagファイルを排他をかけて作成し、排他がとれなかったらそのまま書くという意味なら、それでいいと思います。 OSがUnix/Linuxなら、ログは自分で実装せずにsyslogに任せるのが一番いいと思いますけど。 あとは、ファイルサイズの制限が緩いのなら、処理プロセスでは切り替えを全く行わずにひたすら書いて、別途一定時間ごとに「ファイルサイズをチェックして越えてたら切り替える」というプロセスを起動するとか。

jg1wjz
質問者

お礼

ありがとうございます。 見た目も動きも、一番影響が無く軽い手直しで済ませるには・・・と 思っているのですが、overflagを使うことも あまり自信がありません。 OSはwindowsです。 他のプロセスを立てることも大きな変更になりますし。 迷っています。 先ほど保守の方に確認したところ、 とりあえず、特に問題がおきていないので今のままで様子を見て、 (問題がおきたときにログが無いのは大変困るのですが^^;) 次月にも小さなログがあるようなら、対処を入れましょう...になりました。 対処する際にはサイズチェックする今の方法ではなく、 日付けごとにログを残す方法にして 古いログは保守作業の際に消していくように変更してもらおうと思います。 アドバイス有難うございました。 今後ともよろしくお願いします。

関連するQ&A

  • 排他処理について教えてください。

    現在、ガンダムカルトQQQ(MIDI-CG-SOFT-総合サイト)【http://ha1.seikyou.ne.jp/home/jun/】様よりフリーで配布されている「QQQ MEMBERS ver1.00」を使用してメンバー管理を行なっています。 しかし、このスクリプトには排他処理が入っていなかった為、ディスカバリーシステム【http://www.dscvsys.com/Perl.htm#filelock】様のページを参考にrenameを使った排他処理を作成しましたが、どこに排他処理をかけていいかわからず、かなり悩んでいます。 *排他処理はディスカバリーシステム様の記述をそのまんま使用しています。 尚、ファイル構成は以下の通りです。 cgi-bin  |  ├member.cgi  ├jcode.pl  └lockdir    └lockfile(拡張子無しテキストファイル) 大変申し訳ありませんがご教授宜しくお願い致します。

    • ベストアンサー
    • CGI
  • 排他処理について

    http://www.tryhp.net/lock.htm このサイトの排他処理を参考に組んでいるのですが、 「7.完成」のソース、「#ロックされていなければロックする」以降に出てくる$tmpfileについての質問です。 この変数$tmpfileにはテンポラリ用にこちらで用意したファイル名が入っているということでしょうか? リネームするのであれば rename($tmp_dummy,$datafile); かなと考えていたのですが…。 ソース上部でも$tmpfileのテンポラリを作成していないので不思議です。 意図が読めずに困っております。お知恵を拝借したいと思います。

    • ベストアンサー
    • Perl
  • 排他処理

    こんにちは。 定期的にperlスクリプトを動かしてファイルを作成し、http(Apache)でそのファイルを参照するシステムを作成中です。 このとき、作成中の中途半端なファイルを読まないようにしたいのですが、 どのようにするのがよいでしょうか? CGIスクリプトで掲示板等のファイルにアクセスする際の排他制御についてなら、いろいろと情報もあるのですが、今回のようなケースについてはどうも情報が見つかりませんでした。 単純にテンポラリファイルを作って最後にrenameするだけでもよさそうなのですが、どの程度確実なものでしょうか。 あるいはapacheの設定でなにかうまい方法があるのでしょうか? どなたかご存知でしたら、ご教示願います。 OSはSolarisです。よろしくお願いします。

    • 締切済み
    • CGI
  • ファイルの排他

    ログの出力/照会時の排他処理について、教えて下さい。 環境 言語:VC++/CLI OS:Win VISTA 前提 ログ出力 ・APL起動時にログファイルをオープンする。  (基本的にはオープンしっぱなし) ・メッセージ受信などイベント取得時にログに書き込む。  (複数スレッドからの書込み処理あり) ・最大行数に達したら、ファイルをクローズして、  新規にファイルをオープンしてそちらに書き込む。  (aaa_1.log, aaa_2.log,・・・という具合) ログ照会 ・画面からボタン押下で今まで書き込んだログを照会する。 ・ログ照会時はオープン→リード→クローズとなります。 質問 複数スレッドから書込み処理がある場合に備えて排他をかける 「読み込み時に書込み発生(EOFがおかしくなるとか)」や 「書込み時に読み込み発生(行の半端なところで表示されるとか)」など、バッティングした際を考慮した排他のかけ方 について注意点があればご教授頂きたいのですが・・・ 単純に以下のような実装イメージでよろしいのでしょうか? //////////////////////////////////// 書込み処理 //変数定義 StreamWriter^ sw = nullptr; 起動時 メソッド1 sw = gcnew StreamWriter( "TestFile.txt" ); 最大行数に達したら メソッド2 sw->Close(); sw = gcnew StreamWriter( "TestFile2.txt" ); //イベント発生 メソッド3 //排他処理 sw->WriteLine( "aaaa" ); //排他解除 //////////////////////////////////// //////////////////////////////////// 照会処理 //n=ファイルサイズを求めておく; //排他処理 StreamReader^ sr = gcnew StreamReader( "TestFile.txt" ); array<Char>^c = nullptr; while ( sr->Peek() >= 0 ) { c = gcnew array<Char>(n); sr->Read( c, 0, c->Length ); //ある理由でReadLineが                  //使えそうにないです                  //理由を説明すると                  //長くなりそうなので                  //省かせて下さい //画面出力領域 ← c } sr->Close(); //排他解除 //////////////////////////////////// 以上、宜しくお願い致します。

  • ネットワーク上のファイルの排他

    No.872814 SCSI HDDのファイルシステム?関連で追加で疑問です。 複数のPCと(SCSI等で)接続した一台のディスクは、PC間で排他されないとのことですが、普通のネットワークコンピュータによるファイル共有はどのように排他されているのでしょう? Windows側が排他しているんでしょうか。 にしても、ディスク側にも排他中の情報がありそうに思います。 ディスク内のファイルシステムだけで排他を制御しているなら、複数PCと(SCSI等で)接続した一台のディスクも同じように排他できるのでは?と素人考えしてしまいますが、どうでしょう。

  • ftpコマンドで複数のファイルを移動させたい

    Solaris からftpコマンドを使用してwindosサーバに接続し、複数のファイルを./bak/フォルダにまとめて移動させたいのです。 renameを使えば、1つのファイルでなら可能ですが、複数は無理のようです。 rename test01.txt ./bak/test01.txt→OK rename *.txt ./bak/*.txt    →NG なんとかftpで複数ファイルの移動は出来ないのでしょうか? 1つずつ移動させるしかないのでしょうか?対象ファイルがたくさんあるので、それは避けたいのですが…。 ご教示願えればと思います。

  • CFile::Renameで書き込み途中のファイルがリネームされて困っ

    CFile::Renameで書き込み途中のファイルがリネームされて困っています。 ファイル書き込み中のファイルはリネームしない方法はあるのでしょうか? ファイルのリネーム(CFile::Rename)関数を使用してフォルダ内にあるファイル名をリネームする処理を作成しています。 フォルダ内にはA_で始まるファイルが複数存在し、一定周期で別のスレッドからA_で始まるファイルが書き込まれている状態です。 私が作成している処理は、そのフォルダにA_で始まるファイルが存在する場合に、A_をRename関数でB_にリネームしています。 ここで、別スレッドがA_で始まる新しいファイルを書き込みしている最中に私が作成している処理でRename関数が実行されると、基本的にはExceptionが発生するのですが、Exceptionが発生せずに書き込み途中のファイルがRenameされてしまっています。 1.A_XXX001.txtに書き込み中(100行目まで書き込み完了) 2.Rename処理が実行される。 3.B_XXX001.txtが作成される(100行目までのファイル 作成日:2010.02.04 10:00) 4.その後もA_XXX001.txtに書き込みが行われ200行目まで書き込んで終了 (作成日:2010.02.04 10:02) 結果:B_XXX001.txtファイルは不完全なファイルとして作成されてしまっています。 このような現象が起こってしまっています。 どなたかご教授願います。

  • 排他ロックが掛かっているファイルを読み込む

    排他ロックが掛かっている(別のプロセスが使用している) テキストファイルを読み込みたいのですが、 System.IO.FileStreamを実行した後に、IOExceptionエラーが発生し、 読み込みができません。 System.IO.FileStreamにはこだわってませんので、 排他ロックが掛かっているテキストファイルを読み込む方法を ご存知の方は、ご教授頂けませんでしょうか。 宜しくお願いします。 <ソースコード> 'ファイルパス wFullPath = "\\XXX.XXX.XXX.XXX\TEXT\TEST.TXT" (XXX.XXX.XXX.XXX:IPアドレス) 'ファイルを開く Dim fs As New System.IO.FileStream(wFullPath, _ System.IO.FileMode.Open, _ System.IO.FileAccess.ReadWrite, _ System.IO.FileShare.ReadWrite) 'FileStreamを基にしたStringReaderのインスタンスを作成 Dim enc As System.Text.Encoding = _ System.Text.Encoding.GetEncoding("shift_jis") Dim sr As New System.IO.StreamReader(fs, enc) 'ファイルの内容をすべて読み込む Dim s As String = sr.ReadToEnd() <開発環境> 言語:VB.NET Microsoft Visual Studio 2008 Microsoft .NET Framework Version 3.5 SP1

  • ファイルの排他について

    はじめまして。 初心者ですが、今非常に困っております。 RandomAccessFileを使用して、ファイルの排他をしたいのですが・・・。具体的に言うと、AがAAA.xmlをOPEN中にBがAAA.xmlをOPENしようとするとAがOPEN中なので、例外処理に飛ばしたいのです。いくら試みても例外処理に飛びません。 <例>(java version "1.3.1.05") try { raf = new RandomAccessFile("AAA.xml","rw"); // OPEN raf.writeBytes(111); // WRITE1 raf.writeBytes(222); // WRITE2 raf.writeBytes(333); // WRITE3 raf.writeBytes(444); // WRITE4 raf.writeBytes(555); // WRITE5 raf.close(); // CLOSE } catch(IOException e) { // 排他制御に失敗. リトライしたい System.out.println("別のプロセス?が使用中") }  心当たりのある方がいらしゃいましたら、ご協力お願い致します。

  • バッチファイルでのエラー処理の方法を教えてください

    バッチファイルでのエラー処理の方法を教えてください 例えば、以下のようなバッチファイルがあったとき echo ▼ フォルダ名を入れ替えます(処理1) cd "C:\Test1" move Work temp move Work_bak Work move temp Work_bak echo ▼ フォルダ名を入れ替えます(処理2) rem cd "C:\Test2" move Work temp move Work_bak Work move temp Work_bak (処理1)の時に、 「プロセスはファイルにアクセスできません。別のプロセスが使用中です。」 等のエラーによって、フォルダ名の変更ができなかったとき、 そのエラーがでた以降の処理を行いたくないのですが、 どのように書けばよろしいのでしょうか? 宜しくお願いいたします。 OSはWindows系です。

専門家に質問してみよう