【问题标题】:Locking files. What to do first? Unlock or close?锁定文件。首先要做什么?解锁还是关闭?
【发布时间】:2013-03-19 00:05:10
【问题描述】:

我先解锁然后关闭。 一个过程附加记录 ABCDEFGHIJ。 另一个进程读取同一个文件并写入 ZZZZ。 普通文件应该是 ZZZZ ABCDEFGHIJ

但只有一次我看到了以下内容: ZZZZEFGHIJ 所以记录 ABCDEFGHIJ 被 ZZZZ 损坏了。

看来我的锁定不起作用。 但我测试了它。一个进程真的在等待另一个进程。 另一个进程可以在打开和锁定之间写入文件吗? 还是在解锁和关闭之间?

代码如下

int MyOpenWrite(char *name,int flags) {
int fd
fd = open(name,flags,S_IREAD|S_IWRITE|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
LockFile(fd);
return fd;
 }

int WriteFile(char *name, char *data) {
...
fd = MyOpenWrite(fullName,O_CREAT|O_WRONLY|O_TRUNC);
write(fd,data,strlen(data));
UnLockFile(fd);
close(fd);
}

int ReadFile(char *name, char *data, int maxLength) {
fd = open(name,O_RDONLY);
LockFile(fd);
...
UnLockFile(fd);
close(fd);
}

int AppendFile(char *name, char *data) {
fd = MyOpenWrite(fullName,O_WRONLY|O_APPEND);
...
len=write(fd,data,strlen(data));
UnLockFile(fd);
close(fd);
 }

int LockFile(int fd) {
struct flock    lock;
lock.l_type = F_WRLCK;
lock.l_start = 0;
lock.l_whence = SEEK_SET;
lock.l_len = 0;
return fcntl(fd,F_SETLKW,&lock);
}

int UnLockFile(int fd)  {
struct flock    lock;
lock.l_type = F_UNLCK;
lock.l_start = 0;
lock.l_whence = SEEK_SET;
lock.l_len = 0;
return fcntl(fd,F_SETLKW,&lock);
}

我尝试关闭(fd)UnLock(fd)。 它似乎有效。 但是无论如何,打开和锁定之间存在延迟。 谢谢。

【问题讨论】:

  • 也许你应该在解锁之前刷新文件?
  • 嗯。我怀疑。Flush 只是写入硬盘。我认为如果文件没有写入硬盘并且第二个进程读取它,它应该从现金中读取它,而不是从硬盘中读取。
  • 不,fflush-ing 文件实际上是写入文件。
  • fflush 刷新 stdio 缓冲区。它不保证这些位是由内核物理写入磁盘的。为此,您需要fsync
  • 您无法保证进程 A 和 B 共享文件 I/O 缓存。

标签: c linux locking cgi-bin


【解决方案1】:

只要不write(2)到文件(解锁后),先解锁还是先close(2)都无所谓。

但是,close(2)-ing 文件会解锁它(至少如果没有其他进程共享相同的打开文件描述符)。

fcntl(2) 上面写着

As well as being removed by an explicit F_UNLCK, record locks are
automatically released when the process terminates or if it closes any
file descriptor referring to a file on which locks are held.

附录:应该检查失败

请注意,您的代码缺少错误检查。几乎每个库函数或系统调用,特别是 fcntlreadwrite,都可能失败(并在某些日志或打印中设置 errno 以显示为例如 perrorstrerror(errno))。您不会在 LockFileUnlockFile 函数中检查 fcntl 的成功或失败,也不会在调用者中检查。

【讨论】:

  • 我明白了。但是我的锁有什么问题,如果它不起作用?
  • 你应该检查失败,正如我刚刚添加的那样。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-30
  • 1970-01-01
  • 2011-09-25
  • 1970-01-01
  • 2012-09-09
相关资源
最近更新 更多