C:线程安全日志记录到文件

Sup*_*ron 5 c file thread-safety

我正在尝试编写一个线程安全的C日志记录函数,我对文件IO有一些严重的问题.所以,基本上,我从一个有趣的fopen调用开始,让我以二进制更新模式打开日志:

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+");
Run Code Online (Sandbox Code Playgroud)

接下来,我锁定文件,如果另一个线程锁定它太久,则包含超时:

//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);
}
Run Code Online (Sandbox Code Playgroud)

最后,我将所需的消息添加到文件的末尾,解锁并关闭文件:

//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);
Run Code Online (Sandbox Code Playgroud)

但是,似乎大多数消息都被覆盖在日志中,而不是附加,几乎就像fopen是对文件进行"快照",等待它被解锁,然后写入文件末尾的位置.如果另一个进程没有添加它.有没有人知道如何解决这个问题?

顺便说一句,我希望处于二进制更新模式,因为我最终会添加一些修剪功能,以确保日志文件不超过一定的大小,这对我来说更容易通过工作fseek调用和R/W功能完成.

任何提示都表示赞赏.先谢谢!

use*_*342 5

fflush()在解锁之前没有调用文件指针.这样,您的日志消息保留在stdio缓冲区中fclose(),在不再保持锁定时写入.

要解决此问题,请fflush(log)在解锁操作之前添加一个,或者只是在fclose(log)之前移动它.

  • 是的,就是这样.谢谢! (2认同)