[APUE]请问父母和孩子共享相同的文件后叉偏移? [英] [APUE]Does parent and child share the same file offset after fork?

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

问题描述

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

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

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

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

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

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


  

[Langzi @自由APUE] $猫race.out

  这是一个很长很长outputhis从父输出长长


看来家长和孩子有独立的文件偏移量,而不是共享相同的偏移。

有没有在我的code任何错误?还是我误解共享抵消意思?

任何的建议和帮助将AP preciated。

以下是我的code:

 的#includeapue.h
#包括LT&;&fcntl.h GT;无效charatatime(INT FD,字符*);诠释的main()
{
 将为pid_t PID;
 INT的fd;
 如果((FD =打开(race.out(O_WRONLY | O_CREAT | O_TRUNC)
     S_IRUSR | S_IWUSR))≤; 0)
  err_sys(打开错误); 如果((PID =叉())℃,)
  err_sys(叉错误);
 否则,如果(PID == 0)
  charatatime(FD,这是从小孩\\ N久长输出);
 其他
  charatatime(FD,这是从父\\ N久长输出); 出口(0);
}
无效charatatime(INT FD,字符*海峡)
{
 //尽量使两个过程频繁地切换越好
 //证明了比赛的状态。
 //为FD设置同步标志
 set_fl(FD,O_SYNC);
 而(* STR){
  写(FD,STR + 1);
  //确保数据写入磁盘
  fdatasync(FD);
 }
}


解决方案

好吧,我错了。

因此​​,他们正在共享的偏移,但别的东西奇怪的是怎么回事。如果他们不共享的偏移量,你会得到一个看起来像这样的输出:

 这是从一个chredt输出很长很长

,因为每个将开始在它自己的写偏移0和在时间前进一个字符。他们不会相互矛盾开始一下一下地写入文件,直到到了句子的最后一个字,这最终会交错。

因此​​,他们正在共享的偏移量。

但奇怪的是,它似乎并不像偏移量是越来越原子更新,因为没有处理输出显示在满。这就像一个某些部分覆盖其他的一些地方,尽管他们也提前偏移,这样始终不会发生。

如果偏移没有被共享的,你最终会与文件时间最长的两个字符串的准确的字节数。

如果偏移是共用的,原子方式更新,你结束了在文件中完全一样多字节字符串都放在一起。

但你最终得到一个数字,就是介于两者之间的文件中的字节,这意味着offesets是共享的,而不是原子方式更新,而这只是普通的怪异。但是,显然是发生了什么。如何离奇。


  1. 过程的偏移读入A.offset

  2. 进程B偏移读入B.offset

  3. 过程的在A.offset写字节

  4. 过程的集合偏移量= A.offset + 1

  5. 进程B在B.offset写字节

  6. 过程的偏移读入A.offset

  7. 进程B组偏移= B.offset + 1

  8. 过程的在A.offset写字节

  9. 过程的集合偏移量= A.offset + 1

  10. 进程B偏移读入B.offset

  11. 进程B在B.offset写字节

  12. 进程B组偏移= B.offset + 1

这是大约事件序列必须是什么。如何很奇怪。

在$ P $垫和pwrite系统调用存在,因此两个进程可以更新在特定位置的文件,而无需在比赛谁是全球性的偏移值的胜利。

In APUE section 8.3 fork function, about file sharing between parent and child processes,
It said: It is important that the parent and the child share the same file offset.

And in section 8.9 Race Conditions, there is a example: both parent and child write to
a file which is opened before invoking fork function. The program contains a race condition,
because the output depends on the order in which the processes are run by the kernel and for how long each process runs.

But in my test code, the output are overlapped.

[Langzi@Freedom apue]$ cat race.out
this is a long long outputhis is a long long output from parent

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]请问父母和孩子共享相同的文件后叉偏移?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆