2014-09-29

bashで排他制御を実現する

まずはテストファイルを作成
$ seq 10 > /tmp/test
$ cat /tmp/test
1
2
3
4
5
6
7
8
9
10

ここから先頭行を取り出して/tmp/resultに追記し、先頭行を削除するという処理を10回実施してみる

■ダメな例
※/tmp/testから10行削除は成功しているが、抽出して/tmp/resultに追記した値が削除した行と一致していない
$ for i in `seq 10`
do
  head -1 /tmp/test >> /tmp/result;sed -i '1d' /tmp/test &
done
[1] 28066
[2] 28068
[1]-  終了      sed -i '1d' /tmp/test
[3] 28070
[2]-  終了      sed -i '1d' /tmp/test
[4] 28072
[3]-  終了      sed -i '1d' /tmp/test
[4]+  終了      sed -i '1d' /tmp/test
[1] 28074
[2] 28076
[1]-  終了      sed -i '1d' /tmp/test
[2]+  終了      sed -i '1d' /tmp/test
[1] 28078
[2] 28080
[1]-  終了      sed -i '1d' /tmp/test
[3] 28082
[2]-  終了      sed -i '1d' /tmp/test
[4] 28084
[3]-  終了      sed -i '1d' /tmp/test
[4]+  終了      sed -i '1d' /tmp/test
$ cat /tmp/test
$ cat /tmp/result
1
1
2
4
4
5
7
7
9
9

■良い例
flockを利用する
/tmp/testから削除した行と、/tmp/resultに追記した値が一致している
$ touch /tmp/test.lock
$ for i in `seq 10`
> do
>   flock -x /tmp/test.lock -c "head -1 /tmp/test >> /tmp/result;sed -i '1d' /tmp/test" &
> done
[1] 28111
[1]+  終了      sed -i '1d' /tmp/test
[1] 28114
[1]+  終了      sed -i '1d' /tmp/test
[1] 28117
[1]+  終了      sed -i '1d' /tmp/test
[1] 28120
[1]+  終了      sed -i '1d' /tmp/test
[1] 28123
[1]+  終了      sed -i '1d' /tmp/test
[1] 28126
[1]+  終了      sed -i '1d' /tmp/test
[1] 28129
[1]+  終了      sed -i '1d' /tmp/test
[1] 28132
[1]+  終了      sed -i '1d' /tmp/test
[1] 28135
[1]+  終了      sed -i '1d' /tmp/test
[1] 28138
[1]+  終了      sed -i '1d' /tmp/test
$ cat /tmp/test
$ cat /tmp/result
1
2
3
4
5
6
7
8
9
10

0 件のコメント:

コメントを投稿