1

これは私の未解決の試験問題です。2 つの Unix プロセスが、1 つのファイル内の異なる位置に同時に書き込むことはできますか?

  1. はい、2 つのプロセスには独自のファイル テーブル エントリがあります。
  2. いいえ、共有 i ノードには単一のオフセット ポインタが含まれます
  3. 1 つのプロセスだけが書き込み権限を持つ
  4. はい、ただし NFS を使用して運用している場合のみ
4

3 に答える 3

3
  • inode にはファイル オフセットが記録されていないため、回答 2. は正しくありません。
  • プロセスのアクセス権を変更する理由は文書化されていないため、3. は正しくありません。
  • NFS では、異なるホスト上のプロセスによる同時アクセスが可能です。ここでの質問は、同じホスト上のプロセスに関するものであるため、NFS は違いを生むべきではありません。

残りの答え 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
于 2013-10-30T07:28:14.090 に答える
2

定義:

はい、2 つのプロセスには独自のファイル テーブル エントリがあります。

ファイルが open 関数で 2 回開かれると、2 つのファイル記述子が作成されます。

各ファイル記述子には、個別のファイル ステータス フラグがあります。

そのため、2 つのファイル記述子には書き込み権限があり、ファイル記述子 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);
    }
  }

出力:その後、私の出力は

私の名前は空のファイルを条件付けています。

于 2013-10-30T07:59:06.570 に答える
1

はい、もちろんできますが、次の注意事項があります。

  • モードによってはopen()、1 つのプロセスでファイルの内容を簡単に消去できます
  • スケジューリングによっては、書き込み操作の順序が確定的ではない
  • (一般に) 必須のロックはありません。注意深い設計では、アドバイザリ ロックが必要です。
  • バッファリングされた I/O を使用して同じ領域に書き込むと、結果が非​​決定的になる可能性があります。
于 2013-10-29T22:19:57.237 に答える