两个Unix进程可以同时写入单个文件中的不同位置吗?

时间:2013-10-29 19:45:55

标签: unix filesystems

这是我未解决的考试问题。 两个Unix进程可以同时写入不同的位置 在一个文件中?

  1. 是的,这两个进程将拥有自己的文件表条目
  2. 不,共享的i节点包含一个偏移量指针
  3. 只有一个进程具有写权限
  4. 是的,但只有我们使用NFS操作

3 个答案:

答案 0 :(得分:2)

<强>定义

是的,这两个进程将拥有自己的文件表条目。

如果使用open函数打开文件两次,则会创建两个文件描述符。

每个文件描述符都有单独的文件状态标志。

因此,两个文件描述符具有写权限文件descriptor1,文件描述符2具有指向文件的第一个字符的初始位置。

如果我们为描述符和写入文件指定一些位置,则可以轻松测试。

file.txt的内容

我叫Chandru。这是一个空文件。

进行测试编码:

#include<stdio.h>                                                                           
#include<fcntl.h>
#include<stdlib.h>


 main()
 {
    int fd1, fd2;

 if((fd1=open("file.txt", O_WRONLY)) <0){
            perror("Error");
            exit(0);
    }
    if((fd2=open("file.txt", O_WRONLY)) < 0) {
            perror("Error");
            exit(0);
    }
    if(lseek(fd1,20,SEEK_SET) != 20)
    {
            printf("Cannot seek\n");
            exit(0);
    }
    if(write(fd1,"testing",7) != 7)
    {
            printf("Error write\n");
            exit(0);
    }
    if(lseek(fd2,10,SEEK_SET) != 10)
    {
            printf("Cannot seek\n");
            exit(0);
    }
    if(write(fd2,"condition",9) != 9)
    {
            printf("Error write\n");
            exit(0);
    }
  }

<强>输出: 之后我的输出是

我的名字是条件空文件。

答案 1 :(得分:1)

是的,他们当然可以提出以下警告:

  • 根据open()模式,一个进程可以轻松擦除文件内容
  • 根据计划,写入操作的顺序不是确定性的
  • 没有强制锁定(通常) - 仔细设计调用咨询锁定。
  • 如果使用缓冲I / O在同一区域写入,则结果可能是不确定的。

答案 2 :(得分:1)

  • inode中没有记录文件偏移,因此答案2不正确。
  • 没有记录原因让流程修改其访问权限,因此3.不正确。
  • NFS允许不同主机上的进程同时访问,这里的问题是同一主机上的进程,因此NFS不应该有所作为。

这是一个shell脚本,演示了剩下的答案1.是正确的:

# create a 10m file
dd if=/dev/zero of=/var/tmp/file bs=1024k count=10

# create two 1 MB files
cd /tmp
printf "aaaaaaaa" > aa
printf "bbbbbbbb" > bb
i=0
while [ $i -lt 17 ]; do
  cat aa aa > aa.new && mv aa.new aa
  cat bb bb > bb.new && mv bb.new bb
  i=$((i+1))
done

ls -lG /var/tmp/file /tmp/aa /tmp/bb

# launch 10 processes that will write at different locations in the same file.
# Uses dd notrunc option for the file not to be truncated
# Uses GNU dd fdatasync option for unbuffered writes

i=0
while [ $i -lt 5 ]; do
  (
  dd if=/tmp/aa of=/var/tmp/file conv=notrunc,fdatasync bs=1024k count=1 seek=$((i*2)) 2>/dev/null &
  dd if=/tmp/bb of=/var/tmp/file conv=notrunc,fdatasync bs=1024k count=1 seek=$((i*2+1)) 2>/dev/null &
  ) &
  i=$((i+1))
done

# Check concurrency
printf "\n%d processes are currently writing to /var/tmp/file\n" "$(fuser /var/tmp/file 2>/dev/null | wc -w)"

# Wait for write completion and check file contents
wait
printf "/var/tmp/file contains:\n"
od -c /var/tmp/file

它的输出成功显示了10个进程并同时写入同一个文件:

-rw-r--r-- 1 jlliagre  1048576 oct.  30 08:25 /tmp/aa
-rw-r--r-- 1 jlliagre  1048576 oct.  30 08:25 /tmp/bb
-rw-r--r-- 1 jlliagre 10485760 oct.  30 08:25 /var/tmp/file

10 processes are currently writing to /var/tmp/file

/var/tmp/file contains:
0000000   a   a   a   a   a   a   a   a   a   a   a   a   a   a   a   a
*
4000000   b   b   b   b   b   b   b   b   b   b   b   b   b   b   b   b
*
10000000   a   a   a   a   a   a   a   a   a   a   a   a   a   a   a   a
*
14000000   b   b   b   b   b   b   b   b   b   b   b   b   b   b   b   b
*
20000000   a   a   a   a   a   a   a   a   a   a   a   a   a   a   a   a
*
24000000   b   b   b   b   b   b   b   b   b   b   b   b   b   b   b   b
*
30000000   a   a   a   a   a   a   a   a   a   a   a   a   a   a   a   a
*
34000000   b   b   b   b   b   b   b   b   b   b   b   b   b   b   b   b
*
40000000   a   a   a   a   a   a   a   a   a   a   a   a   a   a   a   a
*
44000000   b   b   b   b   b   b   b   b   b   b   b   b   b   b   b   b
*
50000000