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功能完成.
任何提示都表示赞赏.先谢谢!
fflush()在解锁之前没有调用文件指针.这样,您的日志消息保留在stdio缓冲区中fclose(),在不再保持锁定时写入.
要解决此问题,请fflush(log)在解锁操作之前添加一个,或者只是在fclose(log)之前移动它.