primefaces打开并locking文件

我有一个文件foo.hex是由两个进程访问。 一个进程有O_RDONLY访问,另一个进程有O_RDWR访问。

当第一次启动系统时,在写入过程初始化之前,读取过程不应该访问文件。

因此,我写了这样的东西来初始化文件。

 fd = open("foo.hex", O_RDWR|O_CREAT, 0666); flock(fd, LOCK_EX); init_structures(fd); flock(fd, LOCK_UN); 

这仍然给读者程序在初始化之前访问文件的可能性。

我找不到以primefaces方式open()flock()的方法。 除了互斥体之外,还有什么其他可能性可以通过尽可能less的开销以优雅的方式实现我的目标(因为只有一次,系统第一次启动)?

让作者创建一个名为“foo.hex.init”的文件,并将其重命名为“foo.hex”之前进行初始化。 这样,读者永远不会看到未初始化的文件内容。

另一种方法是让读者进程稍微休息一下,然后重新发现文件还不存在或是空的。

 int open_for_read(const char *fname) { int retries = 0; for (;;) { int fd = open(fname, O_RDONLY); if (fd == -1) { if (errno != ENOENT) return -1; goto retry; } if (flock(fd, LOCK_SH)) { close(fd); return -1; } struct stat st; if (fstat(fd, &st)) { close(fd); return -1; } if (st.st_size == 0) { close(fd); goto retry; } return fd; retry: if (++retries > MAX_RETRIES) return -1; sleep(1); } /* not reached */ } 

在写入方面你需要类似的代码,所以如果作者输了,不必重新启动。

另一种方法可能是删除现有的文件,重新创建它,而无需任何进程访问它的权限,然后在写入文件后更改文件权限:

 unlink("foo.hex"); fd = open("foo.hex", O_RDWR|O_CREAT|O_EXCL, 0); init_structures(fd); fchmod(fd, 0666); 

如果你以root身份运行,这可能不会起作用。 (你不应该这样做…)

这将阻止任何进程使用旧数据一旦unlink()调用。 根据您的要求,这可能或不值得额外的读取器代码来处理文件不存在或在新文件被初始化时可访问。

就个人而言,除非init_structures()花费大量时间,否则我会使用rename( "foo.hex.init", "foo.hex" )解决方案,并且一旦有新数据可用,就不要使用旧数据。 但有时候重要的人使用旧数据并不舒服,而新数据的任何部分都是可用的,他们并不真正理解,“如果读者进程在两毫秒之前就开始使用旧数据。

进程间通信有很多种方法。

也许在打开和初始化文件之前使用写入过程锁定的命名信号? 然后读取过程也可以尝试锁定信号量,如果成功,并且文件不存在,则解锁信号量并稍等片刻,然后重试。

最简单的方法,特别是如果每​​次都会通过写作过程重新创建文件,那么John Zwinck已经在回答这个问题了 。