我有一个创建自身的多个实例(进程)的应用程序,这些进程具有共享数据结构。在该结构中,有一个文件描述符用于将数据记录到文件中。在日志记录功能中检查是否检查文件描述符是否为-1,如果是,则打开文件并设置共享文件描述符的值。
其他进程/线程执行相同的检查,但此时fd为!= -1。所以文件没有打开。然后他们继续写入文件。写入大部分时间失败并返回-1。当写入没有失败时,我使用readlink检查了fd的文件路径。该路径是除日志文件之外的其他文件。
我假设这是因为即使文件描述符值始终为11,即使在后续运行中,该值也会引用每个进程的不同文件。那么进程已经打开了第11个文件?因此,日志文件甚至不被视为对这些进程开放,即使它们打开文件,fd也会不同。
所以我的问题是正确的吗?我的第二个问题是,如果多个进程需要写入此日志文件,我该如何重新实现此方法。每个进程是否需要打开该文件..或者是否有另一种更有效的方式..我是否需要关闭该文件以便其他进程可以打开并写入它??
编辑:
该软件是一个名为filebench的开源软件。 该文件可以看到here。
Log方法是filebench_log。 204行是我提到的文件打开的第一个检查。写入发生在第293行.fd值在所有进程中是11,并且值相同:11。它实际上通过所有进程和设置共享here。该文件只打开一次(通过打印语句验证)。
具有fd的共享数据结构称为
filebench_shm
,fd是
filebench_shm->shm_log_fd
编辑2: 我得到的错误消息是坏文件描述符。 Errno是9岁。
编辑3: 所以似乎每个进程都有一个不同的fds索引表。维基:
On Linux, the set of file descriptors open in a process can be accessed under the path /proc/PID/fd/, where PID is the process identifier.
所以我遇到的问题是,对于具有进程ID 101,102的两个进程,文件描述符11对于这两个进程是不同的:
/proc/101/fd/11
/proc/102/fd/11
我在这些进程之间有一个共享的数据结构..还有另一种方法我可以在它们之间共享一个打开的文件而不是fd,因为它不起作用吗?
答案 0 :(得分:3)
在生成新进程之前打开文件似乎最简单。通过将文件集中到一个时间和地点,这可以避免关于打开文件的所有协调复杂性。
答案 1 :(得分:2)
我最初把它写成一个解决方案:
- 创建共享内存段。
- 将文件描述符变量放在段中。
- 在段
中放置互斥信号量- 每个进程访问段中的文件描述符。如果它没有打开,请锁定信号量,检查信号量是否打开,如果没有打开信号量 文件。释放互斥锁。
这样所有进程共享相同的文件描述符。
但是这假设底层文件描述符对象也在共享内存中,我认为它不是。
相反,请使用其他答案中提到的open
然后fork
方法,或让每个进程打开文件,并在需要时使用flock
序列化访问权限。