排他を実現するコマンドflock(1)の使い方メモ

Thu Apr 10 20:59:27 JST 2014 (modified: Sun Oct 1 10:50:27 JST 2017)
views: 13983, keywords:コマンド,flock,Linux,排他処理 この記事は最終更新日が7年以上前のものです。

排他をかけるコマンドです。Ubuntuので試しました。

まず、排他区間を設けて処理したい内容をシェルスクリプトにします。ここでは、ひたすらプロセス番号をhogeというファイルに書き続けるシェルスクリプトchild.bashを準備しました。

ueda@remote:~$ cat child.bash 
   #!/bin/bash
   
   for i in {1..10000} ; do
       echo $$ >> hoge 
   done

次に、child.bashを同時に何本も走らすシェルスクリプトparent.bashを次のように準備します。100個並列で走らせます。flockの使い方ですが、最初に鍵となるファイル(これはディレクトリでもよい)を適当に指定して、その次に実行したいコマンド(スクリプトやその他プログラム)を指定します。

ueda@remote:~$ cat parent.bash 
   #!/bin/bash
   
   for i in {1..100} ; do
       flock /home/ueda/lock ./child.bash &
   done

で、実行。無慈悲な攻撃をUbuntuに食らわせます。

ueda@remote:~$ ./parent.bash 
   ueda@remote:~$ 

できたファイルhogeを見てみましょう。プロセス番号が入れ違いになってたら排他失敗となりますが・・・。

###プロセス番号が順番になっている###
   ueda@remote:~$ uniq hoge | head
   27465
   27538
   27547
   27562
   27565
   27568
   27569
   27570
   27571
   27572
   ###(プロセス番号が一周しなければ)ちゃんと順番になっていることがsort -cで分かる###
   ueda@remote:~$ cat hoge | sort 
   c-ueda@remote:~$ echo $?
   0

なんかうまくいってます。プロセス番号が順番になるのは、鍵の取れたchild.bashのプロセスから順番にプロセス番号をもらっていくからでしょう。

次に、もっと無慈悲なchild.bashを用意しました。echoに&をつけて、hogeへの書き込みを非同期にします。

ueda@remote:~$ cat child.bash 
   #!/bin/bash
   
   for i in {1..10000} ; do
       echo $$ >> hoge & 
   done

hogeを一度消去して再実行!

ueda@remote:~$ ./parent.bash 
   ###この場合はプロセス番号が何周もするので、一度uniqをかけてからソートして重複チェックを行う。###
   ###ただ、運が悪いと別のプロセスのchild.bashに同じプロセスIDが渡る。###
   ueda@remote:~$ cat hoge | uniq | sort | sort 
   c-ueda@remote:~$

これもうまくいったようです。

ちなみにflockの部分を除くとこうなります。

ueda@remote:~$ sort -c hoge
   sort: hoge:9680: 順序が不規則: 4507

が、この後、プロセスの立ち上げ過ぎでUbuntuがしばらく気絶しましたとさ。

それはさておき、flock便利だ・・・。

ノート   このエントリーをはてなブックマークに追加 
 

prev:bashで中括弧のグループコマンドをパイプでつなぐとサブシェルで実行されるので一応気をつける next:キシリトールが何で虫歯予防になるのか

やり散らかし一覧

記事いろいろ