日々徒然

プログラミングしたりお酒飲んだりする毎日

Rubyでファイルの排他制御

ファイルの排他制御

File#flock (Ruby 3.0.0 リファレンスマニュアル)でファイルへのロックを取得する

  • File::LOCK_EXは排他ロック
  • File::LOCK_NBをor条件で指定すると以下の時にfalseを返す
    • 他のプロセスが排他ロックをすでに行っている場合にロックを行う
    • 他のプロセスがロックしている状態で排他ロックを行う

lock.txtは空ファイル

File::LOCK_NBあり

# example.rb

File.open("lock.txt", "a+") do |file|
  if file.flock(File::LOCK_EX | File::LOCK_NB)
    file.puts "実行"
    sleep 10
  else
    puts "ロック中のファイルです"
  end
end
~/lock_example via 💎 v2.7.1 took 51s 
# 1回目の実行
❯ ruby example.rb &
[1] 14877

# 2回目の実行
~/lock_example via 💎 v2.7.1 
✦ ❯ ruby example.rb &
[2] 14911


~/lock_example via 💎 v2.7.12 ❯ ロック中のファイルです

[2]  + done       ruby example.rb

~/lock_example via 💎 v2.7.12[1]  + done       ruby example.rb
実行

結果

1回目の実行時にlock.txtのロックが取得されているため、2回目の実行時にflockがfalseを返してロック中のファイルですが出力される

File::LOCK_NBなし

File.open("lock.txt", "a+") do |file|
  if file.flock(File::LOCK_EX)
    file.puts "実行"
    sleep 10
  else
    puts "ロック中のファイルです"
  end
end
~/lock_example via 💎 v2.7.1 
# 1回目の実行
❯ ruby example.rb &
[1] 15303

~/lock_example via 💎 v2.7.1 
# 2回目の実行
✦ ❯ ruby example.rb &
[2] 15340

~/lock_example via 💎 v2.7.12[1]  - done       ruby example.rb

~/lock_example via 💎 v2.7.12[2]  + done       ruby example.rb
実行
実行

結果

1回目の実行時にlock.txtのロックが取得されているため、2回目の実行時にロック解除まで待ち、ロック解除後にファイルへの書き込みを行う