• 締切済み

時刻データが前後します

VC++でログファイルを作成しており、ファイルには事象が発生した日付時刻を組み合わせて保存しています。通常であれば、発生した事象の並びに合わせて時刻も推移していますが、時々、後に発生した事象に対する時刻が、直前の事象に対する時刻より前の時刻が保存されてしまう現象が発生しています。(0.5~1秒強前後ですが。)OSはNT、2000系です。プログラム作成上で要注意項目等あれば教えていただけないでしょうか。  ※1:時間取得には「time()」を使用しています。  ※2:マルチスレッド上でのソフト作成を行っていますが、ログ保存処理には排他制御を施しているつもりです。 よろしくお願いします。

みんなの回答

  • terra5
  • ベストアンサー率34% (574/1662)
回答No.2

ライブラリはマルチスレッド用のを使ってますよね? マルチスレッドの処理内容がわからないとなんとも言えませんが, 時間取得のタイミングや、ログ書き込みのタイミング, 排他制御の方法(期間)の関係で,ログ書き込みの順番が入れ替わる可能性はありませんか? こんな感じで。 スレッド1 スレッド2 時刻取得  ---- ----  時刻取得 ----  ログ書込 ログ書込  ---- このような場合、単にログ書込の排他制御では回避できませんし、 GetTickCount等を使っても回避できません。 この場合なら簡単な回避方法は、排他制御の期間を時刻取得前からログ書込み完了後までにすることです。 性能上の問題とか,長時間になりすぎるとかがある場合は別な方法にする必要がありますが。

  • sha-girl
  • ベストアンサー率52% (430/816)
回答No.1

マルチスレッドが原因でしょうね。 GetTickCount、あるいはGetSysTimeで取得してはどうでしょうか? 基本的に原因は排他制御ができていないのだと思います。 time()で取得した瞬間からログ書込みの間に他のスレッドが time()を実行しているのでしょう。 スレッド1:time()→ログ書込み スレッド2:time()→ログ書込み スレッド1実行中にスレッド2が1サイクルしてしまっているのでは? ログ書込み直前にtime()で取得すれば、誤差は縮まると思います。

関連するQ&A

  • ファイルの排他制御

    VCでのファイルの排他制御の方法を教えてください。 環境WidowsNT4.0 VC6.0 宜しくお願いします

  • 時間が前後します

    Windows2000上でVCを使用してソフトを作成しています。(MFCベース) 処理経過を確認するためにログファイルを保存し、この中にはログを落とす際の日付と現象を保存しています。ここで、日付が前後する現象が発生していることがわかりました。このため経過時間を確認して処理を行っている箇所で、問題が生じています。何か対処方法はないでしょうか。よろしくお願いします。  使用している関数:   時間取得・・・ time(&now_t);   時間差取得・・・double t = difftime(now_t, m_BaseTime);  ソフト構成:   いくつかのスレッドを起動し、各スレッドより同一  のログファイルに保存しています。但し、この際、  クリティカルセクションで競合が発生しないように  配慮しているつもりです。  異常ログの具体例:   A07からB01に移行する際に、10分から  9分に時間が戻っているような感じです。またログ  保存している現象の内容からは、A01~B03の  並びは時系列となっており、現象自体は正常な順序で  保存されています。    2004年04月06日 04時09分59.463秒 A01 2004年04月06日 04時10分00.114秒 A02 2004年04月06日 04時10分03.118秒 A03 2004年04月06日 04時10分03.318秒 A04 2004年04月06日 04時10分03.549秒 A05 2004年04月06日 04時10分03.559秒 A06 2004年04月06日 04時10分03.869秒 A07 2004年04月06日 04時09分08.635秒 B01 2004年04月06日 04時09分08.645秒 B02 2004年04月06日 04時09分08.645秒 B03  以上分かり難い説明と思いますが、よろしくお願い致します。

  • マルチスレッドについて。

    今、大きな配列を元に処理を行うプログラムを作成しています。 シングルスレッドでも十分速度を向上するようチューニングに成功しましたが、マルチスレッド化をすればさらに速度を向上させることができるだろうと考え、先日マルチスレッドかに成功しました。 しかし・・・奇妙な現象が起こりました。 マルチスレッドで性能を引き出すには、排他制御はないほうが良いと考え、メモリは食いますがスレッドに与える入力情報(大きな配列)を2つ用意し、排他制御なしの2スレッドを実行できるようにしました。しかしやはりメモリを消費しすぎてしまうため、配列にアクセスする部分のみ排他制御を行うようクリティカルセクションを設定し入力情報を2スレッドで共有して処理を行うよう組み替えました。 結果、やはり排他制御なしの場合よりはるかにスピードダウンしてしまい、シングルスレッドより少し早い処理時間で終了してしまいました。 余りにも悔しいため、ちょっと危険な実験だとは思いましたが、入力情報を2つのスレッドで共有しているにもかかわらず、排他制御の部分、つまりクリティカルセクションを取り除いて実行してみようと考えました。予想としては同時にアクセスし衝突が起きてエラーで停止してしまうと考えましたが・・・・・・ 結果なぜかエラーなく処理をし続け、普通に終了してしまいました。 これはなぜでしょう? 偶然にも共有情報に同時にアクセスすることがなかったためでしょうか?

  • 一般ユーザーアカウントで時刻同期するには?

    はじめて質問させていただきます。 Windows7 Pro SP1 環境の一般ユーザーアカウントのクライアントPCにて、サーバ(インターネットには接続されていないネットワーク)との時刻同期を取りたいと考えています。 net time コマンドにてスケジュールで時刻同期を取るバッチファイルを作成しましたが、管理者権限がない為時刻の変更が反映されません。 いろいろ調べて、グループポリシーにてユーザーアカウント制御を有効にし、バッチファイルを実行するたびにユーザーアカウントの制御画面で管理者権限のパスワードを入力すれば時刻の変更が反映されるとこまではできるようになりました。 ですが、ユーザーアカウントの制御画面を表示させずに、管理者権限でバッチファイルを実行させたいのですが、その方法がわからずにこちらに質問させていただきました。 上記の要件でバッチファイルを実行させることはできないのか、またはできるのであればその方法を教えていただきたいと思います。 宜しくお願い致します。

  • UNDOデータは物理データベースの何処?

    物理データベースはデータファイル、制御ファイル、REDOログファイルで構成されていますが、 UNDOデータは、REDOログファイルに格納されているのですか? 変更開始前のデータはREDOログファイルから取り出されるのですか? それとも、REDOログファイルからデータファイルにUNDOデータを作成して、データファイルから取り出しているのでしょうか?

  • マルチスレッドについて

    現在”猫でもできる”の87、88章を学んでおります。 まず87章でマルチスレッドの根本的なやり方を学びましたが、いきなり疑問が浮かびました。 _beginthread関数によりスレッドをスタートさせ、この関数で登録した関数内で_endthread関数を実行し終了させていることは分かります。 しかし_beginthread関数で登録した関数に引数を渡す処理がどの部分で行われているのかわかりません。 登録する関数はvoid型で引数はvoid*型でなければいけないことは分かったのですが、プログラムのどこを見てもこの登録した関数に引数を渡す処理が行われていません。 その辺の動作の説明を分かる方でいいのでよろしくお願いします。 そして88章では排他制御のマルチスレッドを行うプログラムの製作を行っているのですが、ちょっとした疑問が浮かびました。 EnterCriticalSection関数、LeaveCriticalSection関数ではさまれたプログラムは排他制御され他からアクセスされない。 この関数はこんな理解で良いんですかね? この理解で行くと、88章で説明していきますが、子ウィンドウを2つ作成しそれぞれのプロシージャ内で排他制御された関数をスレッドとしてスタートしています。 この2つのスレッドの動作についてですが、互いに排他制御関数が記述されているため、動作としてはまず左の子ウィンドウのスレッドが処理されている場合、右の子ウィンドウのスレッドは停止している。そして左の子ウィンドウのスレッドの排他制御が解放されたときに、右の子ウィンドウのスレッドが開始する。 そしてあるとき左の子ウィンドウのクライアントウィンドウ内で右クリックされた場合、その時点で排他制御されたスレッドが終了するのを待ち、終了したらcountを+1する。 こんな動作が行なわれていると理解してよいのでしょうか?

  • DAQの出力ファイルをコピーして、別のファイルを作成し、そのファイルを

    DAQの出力ファイルをコピーして、別のファイルを作成し、そのファイルを元にリアルタイムに解析をしたいのですが、これって可能でしょうか?先のエントリ(http://okwave.jp/qa/q5699052.html)と連関しているのですが、DAQの出力ファイルを排他制御する一手(?)として、出力ファイルをコピーし、別ファイルとして保存して、そのファイルを元に解析出来ないかと考えています。C言語は殆ど分かっていないのですが、私が調べた限りでは、ファイルをコピーする際、やはりfopenを使わないといけないという結論に至りました。すなわち、この方法でも排他制御は出来ないという事になるのだろうと理解しております。どなたか、私の理解が正しいか否か教えていただけますでしょうか。よろしくお願いいたします。

  • ファイルの排他

    ログの出力/照会時の排他処理について、教えて下さい。 環境 言語: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(); //排他解除 //////////////////////////////////// 以上、宜しくお願い致します。

  • ADサーバにおけるログオンログオフ時刻の取得

    勤務実態調査のために社員のログオンID(=社員ID)、クライアントPCのログオン時刻、ログオフ時刻をCSVファイルに吐き出す仕組みを考えています。ADサーバ上で動作するスクリプトを作成したいのですが、どなたか詳しい方、教えていただけませんでしょうか。

  • mfc vc++2005 で構成が正しくない・・・

    vc++2005 mfcで作成したプログラムで上記が出て他のPCで動きません。 mfc以外はファイルのコピーをするとかだけの単純なツールなのでmfcが 悪さしているとは思います。 mfcをスタティックでリンクにして、コード生成のところのマルチスレッドDLLを マルチスレッドに変えるとやはりいけますが、別にあったwindows7ではmfcと コード生成のところを変えなくても問題なくいけました。 vc++2005 redistributable パッケージを入れても変わりません。 mfcは別物なのでしょうか?? ネットを見ているとredistributableパッケージを入れれば大丈夫!!という 感じなのですが。 すいませんがどなたかご教授ください。

専門家に質問してみよう