`flock` がデスクトップ PC ではランダムに失敗しますが、ノートブックでは失敗しません。ハードウェアに欠陥がある可能性がありますか?

`flock` がデスクトップ PC ではランダムに失敗しますが、ノートブックでは失敗しません。ハードウェアに欠陥がある可能性がありますか?

以下のスクリプトを使用して、排他ロックのストレス テストを行っていますflock

私のノートパソコンでは、常に正常に動作します。
しかし、デスクトップ PC で実行すると、ランダムに失敗し、2 つのインスタンスが同時に実行されることがあります (同じロックを取得します)。
どちらも Ubuntu 20.04 を実行しています。

それで、デスクトップのハードウェアに問題があるのではないかと疑っています。RAM の問題でしょうか?

そこで質問なのですが、Flock Missbehavior が提供しているヒントに基づいて、どのハードウェア部分に欠陥があるのか​​を追跡/特定するにはどうすればよいでしょうか?
つまり、どのハードウェアに欠陥があるか (または品質が低い可能性があるか) を指摘できる Flock は何でしょうか?

問題の確認方法:
フルパス スクリプト名に一致する子コマンドを持つすべての flock プロセスを取得します (これは flock が子コマンドとして実行する必要があるものです)。
また、各スクリプトによって実行された作業をログに記録し、そのログに 2 つ以上のインスタンスの同時作業が記録されます。作業は、ロックが取得された場合にのみログに記録されます。
排他的/一意のロックを提供するように flock を正しく構成していない可能性がありますか?
現在、別の端末でもこれを使用しています:
while true;do date;lslocks |grep flock;sleep 1;done

スクリプト: cat >flock.tst.sh;chmod +x flock.tst.sh

#!/bin/bash

LC_NUMERIC=en_US.UTF-8

# HELPERS:
#trash /tmp/flock.tst.log;for((i=0;i<20;i++));do flock.tst.sh&:;done #run this on shell
#pkill -fe flock.tst.sh #end all concurrent children trying to acquire the lock
#while true;do date;lslocks |grep flock;sleep 1;done #use this to check if there is more than one lock acquired, check also the log file to confirm it, and if there is two subsequent WORK on the terminal log, it means a problem happened too

: ${bDaemonizing:=false}
: ${bReport:=false} #help use this to show more log, but will be harder to read it.
: ${bCheck:=false} #help this will let the script check if there is more than one instance working, but it may be slow and make it more difficult to let the problem happen
if ! $bDaemonizing;then
  echo "this IS a daemon script, only one instace runnable"
  flSelf="`realpath $0`"
  
  #set -x 
  while ! bDaemonizing=true flock --timeout=$(bc <<< "0.2+0.0$RANDOM") "$flSelf" "$flSelf" "$@";do
    if $bCheck;then
      strParents="$(nice -n 19 pgrep -f "^flock --timeout=.* $flSelf $flSelf" |tr '\n' ',' |sed -r 's"(.*),"\1"')"
      if [[ -n "$strParents" ]];then
        anDaemonPid=( $(nice -n 19 pgrep --parent "$strParents" -f "$flSelf") )
        if((${#anDaemonPid[*]}>1));then echo "ERROR: more than one daemon, flock failed!? :(";ps --no-headers -o ppid,pid,cmd -p "${anDaemonPid[@]}";fi
        if $bReport && ((${#anDaemonPid[*]}==1));then echo "$$:Wait daemon stop running or 'kill ${anDaemonPid[0]}'";fi #could be: "already running, exiting.", but the new instance may have updated parameters that work as intended now.
      fi
    fi
  done
  
  exit #returns w/e flock does
fi

echo "$$:Work:`date`"
for((i=0;i<60;i++));do
  echo "`\
    echo $i;\
    date;\
    ps --no-headers -o ppid,pid,stat,state,pcpu,rss,cmd -p "$PPID";\
    ps --no-headers -o ppid,pid,stat,state,pcpu,rss,cmd -p "$$";\
  `" >>/tmp/flock.tst.log
  
  sleep 1
done
echo "$$:Done:`date`"


いくつかの結果:
ご覧のとおり、排他ロックはプロセス 1458428 (flock:1458427) と 1438949 (flock:1438941) によって同時に取得されました :(

ログ ファイル (スクリプトによって作成) には、この問題が表示されます (50 秒目に、ロックを取得するべきではない他のインスタンスの 2 秒目のログが発生しました)。

2
Fri 22 Jan 17:03:16 -03 2021
1438953 1458427 S    S  0.0   784 flock --timeout=.22377 /home/myUser/bin/flock.tst.sh /home/myUser/bin/flock.tst.sh
1458427 1458428 S    S  0.0  3852 /bin/bash /home/myUser/bin/flock.tst.sh
50
Fri 22 Jan 17:03:16 -03 2021
1438925 1438941 S    S  0.0   788 flock --timeout=.229687 /home/myUser/bin/flock.tst.sh /home/myUser/bin/flock.tst.sh
1438941 1438949 S    S  0.0  3900 /bin/bash /home/myUser/bin/flock.tst.sh

lslockこれを示します (while with はdateスクリプトのヒントとして表示されます)。

Fri 22 Jan 17:03:16 -03 2021
flock           1459088 FLOCK  1.8K WRITE* 0          0          0 /home/myUser/bin/flock.tst.sh
flock           1458427 FLOCK  1.8K WRITE  0          0          0 /home/myUser/bin/flock.tst.sh
flock           1438941 FLOCK  1.8K WRITE  0          0          0 /home/myUser/bin/flock.tst.sh (deleted)
Fri 22 Jan 17:03:17 -03 2021
flock           1459616 FLOCK  1.8K WRITE* 0          0          0 /home/myUser/bin/flock.tst.sh
flock           1458427 FLOCK  1.8K WRITE  0          0          0 /home/myUser/bin/flock.tst.sh
flock           1438941 FLOCK  1.8K WRITE  0          0          0 /home/myUser/bin/flock.tst.sh (deleted)

ターミナル ログ (多数の同時インスタンスを生成したもの) には次のように表示されます。

1438949:Work:Fri 22 Jan 17:02:23 -03 2021
1458428:Work:Fri 22 Jan 17:03:14 -03 2021
1438949:Done:Fri 22 Jan 17:03:26 -03 2021
1476209:Work:Fri 22 Jan 17:04:02 -03 2021
1458428:Done:Fri 22 Jan 17:04:17 -03 2021

答え1

仮説: この問題が発生する直前にスクリプトを保存しました。エディターがコピーを保存し、そのコピーを元のパスに移動しました。Vimがどのようにこれを実現するかそしてなぜ

実際には、古いロックは古いファイル (inode) に対してまだ保持されていました。これは、…/flock.tst.sh (deleted)の出力でのように表示されました。lslocksしかし、flockスクリプト (その別のインスタンス?) は、パスを使用して生成し続けました。パスが別の inode を指し始めると、新しい inode がflock新しいロックを取得できるようになりました。これは、…/flock.tst.shの出力でのように表示されましたlslocks

2つのロックは独立しており、お互いをブロックすることはできませんでした。違うファイル。Flock は設計どおりに動作しました。

vim実際に、スクリプトのインスタンスを 2 つ実行し (1 つはロックを取得し、もう 1 つはロックの取得を試行し続ける)、それを で開いてすぐに( ) と書き込むことで、結果を再現でき:wます。または、次の操作を実行します。

cp flock.tst.sh foo
mv foo flock.tst.sh

関連情報