【问题标题】:Can two Unix processes simultaneous write to different positions in a single file?两个 Unix 进程可以同时写入单个文件中的不同位置吗?
【发布时间】:2013-10-29 19:45:55
【问题描述】:

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

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

【问题讨论】:

  • 这是一道作业/测试题,不是吗?
  • @PaulProgrammer 是的,待定。
  • 这里提示一下,三个回复是错误的。
  • @jlliagre 你为什么不去做点别的?
  • 如果你在那个问题上已经失败了两次,你应该只剩下两个选择,不是吗?

标签: unix filesystems


【解决方案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

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

-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

【讨论】:

    【解决方案2】:

    定义

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

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

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

    所以这两个文件描述符有一个写权限文件描述符1和文件描述符2的初始位置指向文件的第一个字符。

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

    file.txt的内容

    我的名字是钱德鲁。这是一个空文件。

    测试编码:

    #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);
        }
      }
    

    输出: 之后我的输出是

    我的名字是条件测试空文件。

    【讨论】:

    • 虽然您显示同一文件的多个文件描述符可以同时存在,这确实是重点,但您并没有真正回答关于两个不同进程写入同一个文件的问题,而不是一个过程。
    【解决方案3】:

    是的,他们当然可以,但需要注意以下几点:

    • 根据open() 模式,一个进程可以轻松擦除文件内容
    • 根据调度,写操作的顺序是不确定的
    • 没有强制锁定(通常) - 精心设计需要建议锁定。
    • 如果他们使用缓冲 I/O 写入同一区域,结果可能是不确定的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-09-07
      • 1970-01-01
      • 2010-11-18
      • 2010-12-07
      • 1970-01-01
      • 2012-01-26
      • 1970-01-01
      相关资源
      最近更新 更多