本文介绍了[APUE]请问父母和孩子共享相同的文件后叉偏移?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在APUE 8.3节 fork函数,有关父子进程之间的文件共享,

它说:重要的是,家长和孩子共享同一个文件偏移

和8.9节竞争条件,还有一个例子:双方父母和孩子写

这是调用fork函数之前打开的文件。该计划包含一个竞争条件,

因为输出取决于在其中的处理由内核和多久每个进程运行的运行顺序上

但在我的测试code,输出重叠。

It seems the parent and child have separate file offsets instead of sharing the same offset.

Is there any error in my code? Or did I misunderstand the meaning of sharing offset?
Any advice and help will be appreciated.

following is my code:

#include "apue.h"
#include <fcntl.h>

void charatatime(int fd, char *);

int main()
{
 pid_t pid;
 int fd;
 if ((fd = open("race.out", (O_WRONLY | O_CREAT |  O_TRUNC),
     S_IRUSR | S_IWUSR)) < 0)
  err_sys("open error");

 if ((pid = fork()) < 0)
  err_sys("fork error");
 else if (pid == 0)
  charatatime(fd, "this is a long long output from child\n");
 else
  charatatime(fd, "this is a long long output from parent\n");

 exit(0);
}


void charatatime(int fd, char *str)
{
 // try to make the two processes switch as often as possible
 // to demonstrate the race condition.
 // set synchronous flag for fd
 set_fl(fd, O_SYNC);
 while (*str) {
  write(fd, str++, 1);
  // make sure the data is write to disk
  fdatasync(fd);
 }
}
解决方案

Well, I was wrong.

So, they are sharing an offset, but something else weird is going on. If they weren't sharing an offset you would get output that looked like this:

this is a long long output from chredt

because each would start writing at it's own offset 0 and advancing a character at a time. They wouldn't start conflicting about what to write to the file until the got to the last word of the sentence, which would end up interleaved.

So, they are sharing an offset.

But the weird thing is, it doesn't seem like the offset is getting atomically updated because neither processes output appears in full. It's like some parts of one are overwriting some parts of the other, even though they also advance the offset so that always doesn't happen.

If the offset weren't being shared, you would end up with exactly as many bytes in the file as the longest of the two strings.

If the offsets are shared and updated atomically, you end up with exactly as many bytes in the file as both strings put together.

But you end up with a number of bytes in the file that's somewhere in between, and that implies the offesets are shared and not updated atomically, and that's just plain weird. But that apparently is what happens. How bizarre.

  1. process A reads offset into A.offset
  2. process B reads offset into B.offset
  3. process A writes byte at A.offset
  4. process A sets offset = A.offset + 1
  5. process B writes byte at B.offset
  6. process A reads offset into A.offset
  7. process B sets offset = B.offset + 1
  8. process A writes byte at A.offset
  9. process A sets offset = A.offset + 1
  10. process B reads offset into B.offset
  11. process B writes byte at B.offset
  12. process B sets offset = B.offset + 1

That's approximately what the sequence of events must be. How very strange.

The pread and pwrite system calls exist so two processes can update a file at a particular position without racing over who's value of the global offset wins.

这篇关于[APUE]请问父母和孩子共享相同的文件后叉偏移?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-23 17:11