両方のスクリプトが同じファイルに書き込むと、競合状態は発生しません。

両方のスクリプトが同じファイルに書き込むと、競合状態は発生しません。

同じファイルにエコーされる2つのスクリプトが並列に実行されています。あるスクリプトは+++++++++++++++ファイルをエコーし​​、もう一方のスクリプトはファイルを===========エコーし​​ます。

以下は最初のスクリプトです。

#!/bin/bash
while [ 1==1 ];
do
    echo "+++++++++++++++" >> log.txt
    # commands
done

2番目のスクリプトは次のとおりです。

#!/bin/bash
while [ 1==1 ];
do
    echo "===========" >> log.txt
    # commands
done

log.txtファイルは約1,400,000行を印刷しますが、1行でも++==のような混同される大文字がありませんか?

Linuxはこの混乱を防ぐことができますか?もしそうなら、どうしてそしてなぜ?

答え1

簡単に言えば、このechoコマンドはwriteアトミックシステムコールをトリガーします。

write指定されたすべてのバイトが書き込まれる保証はありませんが、この場合(データが少ない)には書き込まれます。

その後、理論的にはバイトwrite(fd, buffer, n)より少なく書き込み、nプログラムがバイトを書き込むことができるように書き込まれた実際のバイト数を返すことができますbuffer+n

パイプには無制限の容量がないため、パイプでこれが発生する可能性があります。

~からwrite(2)

O_APPEND(2)を使用してファイルを開くと、ファイルオフセットは書き込み前に最初にファイルの終わりに設定されます。ファイルオフセットの調整と書き込みは、アトミックステップで実行されます。

POSIX.1 によれば、count が SSIZE_MAX より大きい場合、結果は実装に従って定義されます。 Linuxの上限の説明を参照してください。

答え2

次の制限を試すことができます。

#!/bin/bash                                                                                                           

outer() {
    rm log.txt
    inner() {
        a=$(perl -e 'print "'$1'"x'$2'')
        while [ 1==1 ];
        do
            echo $a >> log.txt
            # commands                                                                                                
        done
    }
    export -f inner
    timeout 5 bash -c "inner '-' $1" &
    timeout 5 bash -c "inner '+' $1" &
    wait
    sort -u log.txt
}

replace_repeats() {
    # Replace                                                                                                         
    #   ---                                                                                                           
    # with                                                                                                            
    #  -3                                                                                                             
    perl -pe 's/((.)\2+)/"$2".length$1/e'
}
# This is OK                                                                                                          
outer 10 | replace_repeats
outer 100 | replace_repeats
outer 1000 | replace_repeats
outer 4095 | replace_repeats
# This breaks.                                                                                                        
# It should give:                                                                                                     
# +4096                                                                                                               
# -4096                                                                                                               
outer 4096 | replace_repeats

関連情報