スレッドセーフなCのログ機能を記述しようとしていますが、ファイルIOに重大な問題があります。だから、基本的に、私は私がバイナリアップデートモードでログを開くことができます面白いfopen
呼び出しで起動します。C:ファイルへのスレッドセーフのログ
FILE *log, *start;
int timeout = 0, error;
//make file (fails if file exists)
log = fopen(LOG_FILE, "wx");
//Close the file if a new one was created
if(log)
fclose(log);
//Open file in update mode (it must exist for this)
log = fopen(LOG_FILE, "rb+");
次に、私は別のスレッドが長すぎるためにそれをロックした場合、タイムアウトを組み込む、ファイルをロック
//Init other file pointer
start = log;
//Lock file (with timeout)
rewind(start);
error = lockf(fileno(start), F_TLOCK, 0);
while(error == EACCES || error == EAGAIN)
{
//sleep for a bit
usleep(LOCKED_FILE_RETRY_TIME);
//Incremement timeout
timeout += LOCKED_FILE_RETRY_TIME;
//Check for time out
if(timeout > LOCKED_FILE_TIMEOUT)
{
return;
}
//Retry the lock operation
error = lockf(fileno(start), F_TLOCK, 0);
}
そして最後に、私はそれをアンロックし、ファイルの最後に必要なメッセージを追加し、ファイルを閉じます。
//Print log entry
fseek(log, 0, SEEK_END);
fwrite((const void*) log_msg, 1, strlen(log_msg), log);
//Unlock the block
rewind(start);
lockf(fileno(start), F_ULOCK, 0);
//Close file
fclose(log);
をしかし、それは混乱の大多数のように思えます「fopen
」がファイルの「スナップショット」を取って、ロックが解除されるのを待っているかのように、ログに追加されるのではなく、古いものが上書きされ、別のプロセスが追加しなかった場合、それに。どのように私はこの問題を修正するために行くことができるかに関して誰もが考えていますか?
バイナリアップデートモードにしたいのは、最終的にログファイルが一定のサイズを超えないようにするトリミング機能を追加することになるからです。fseek
コールとR/W機能。
ご了承ください。あらかじめありがとう!
デバッガをステップ実行するとどうなりますか? – SecurityMatt
あなたのすべての操作は 'fseek'と' fwrite'を除いて 'start'です。これは期待ですか? – Ganesh
@Ganesh、はい、ファイルの先頭に1つのファイルポインタを置いて、別のものですべての書き込みを行いたいのですが、ロックを解除する前に 'rewind()'を実行するのを忘れた場合や、ファイルの先頭へのポインタ。 – SuperTron