繁体   English   中英

如何从两个进程同步 - 在一个文件上进行原子写入?

[英]How can I synchronize — make atomic — writes on one file from from two processes?

我有两个进程,每个进程写大数据缓冲区,我想控制同步这些进程的写入到一个文件。

处理1写入缓冲器A包括(A1,A2,A3)和处理2写入缓冲器B,包括(B1,B2,B3)。 当我们使用write()系统调用将这些缓冲区写入磁盘到同一个文件时(整个缓冲区一次write(fd, A, sizeof(A))write(fd, A, sizeof(A)) ),文件架构如何?

  • 它是这样的:A,B或B,A可能吗?
  • 或者它可能是这样的:A1,A2,B1,A3,......

我问这个是因为系统调用是原子的。 如果我们写的数据缓冲区太大会发生什么。 它是否像常规磁盘文件的管道?

如果要存在两个缓冲区的内容,则必须打开设置了O_APPEND标志的文件。 append标志在写入之前寻找文件的末尾。 如果没有这个设置,两个进程可能都指向文件的相同或重叠区域,而最后写入的任何一个将覆盖另一个写入的内容。

每次write调用都会写入所请求的字节数。 如果您的进程被信号中断,那么您最终可以进行部分写入 - 返回写入的实际字节数。 无论你是否写入了所有的字节,你都会编写一个连续的文件部分。 你没有得到你提到的交错效果作为你的第二种可能性(例如A1,B1,A2,B2,......)。

如果您只进行部分写作,您的工作方式取决于您。 您可以继续写入(从缓冲区开始偏移先前写入的字节数),也可以放弃写入的其余部分。 只有这样才能获得交错效果。

如果在另一个进程写入之前让一个写入的内容完成很重要,那么在尝试写入任何数据之前,您应该考虑锁定该文件以进行独占写入访问(两个进程都必须检查)。

假设缓冲区大小相等,结果将是A或B,具体取决于最后安排的进程。

write系统调用是原子的,是的,这意味着结果将是A或B,而不是两者的混合。

假设您希望文件中同时包含A和B,则可以使用O_APPEND打开该文件; 请注意,这不适用于NFS。

另一个选择是每个进程跟踪它应该使用哪个文件偏移量,并使用lseek()或pwrite()

对于访问该文件的程序,您肯定需要某种形式的同步,否则最终会出现混乱的文件内容。 write系统调用可以写入比您请求的更少的字节,因此您的块A1,A2或B1,B2可能只是部分写入。 这可能经常发生,或很少发生,具体取决于许多条件。 如果它只在一周内发生一次,那么您将遇到一个可能很难检测到的错误。

作为解决方案,您可以使用文件锁定( man 2 flockman fcntl并搜索锁定)。 另一种可能性是使用信号量( man -k semaphore )来同步你的程序写入或一些其他形式的IPC。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM