Dapatkan kunci baca / tulis eksklusif pada file untuk pembaruan atom

10

Saya ingin memiliki file yang digunakan sebagai penghitung. Pengguna A akan menulis dan menambah nomor ini, sementara Pengguna B meminta untuk membaca file. Mungkinkah Pengguna A dapat mengunci file ini sehingga tidak ada yang dapat membaca atau menulis padanya sampai penulisan Pengguna A selesai?

Saya telah melihat ke dalam flocktetapi tampaknya tidak bisa membuatnya berfungsi seperti yang saya harapkan.

flock -x -w 5 /dev/shm/counter.txt echo "4" >  /dev/shm/counter.txt && sleep 5

Jika ada cara yang lebih tepat untuk mendapatkan file peningkatan atom-seperti ini, itu akan sangat menyenangkan untuk didengar juga!

Cita-cita saya adalah:

LOCK counter.txt; write to counter.txt;

sementara pada waktu yang sama

Read counter.txt; realize it's locked so wait until that lock is finished.
d -_- b
sumber
1
"Sepertinya tidak bisa membuatnya berfungsi seperti yang saya harapkan." Apa yang secara khusus apakah itu berarti?
John1024
Saya yakin saya salah menggunakannya, tetapi ketika menggunakan kode di atas saya dapat menggunakan dua shell dan meminta mereka mengedit file counter sementara saya pikir ada yang menguncinya. Jadi jika saya menjalankan baris itu dua kali pada dua cangkang terpisah, (masing-masing dengan nomor sendiri untuk gema), saya masih melihat nomor kedua sedang ditulis
d -_- b
1
Ketika yang pertama selesai dan melepaskan kuncinya, yang kedua berjalan. Bukankah itu cara kerjanya? (Dalam kode di atas, && sleep 5dieksekusi setelah kawanan melepaskan kunci.)
John1024
Hmm memotong ... Jadi dalam kasus itu akan terlalu cepat bagi mata manusia saya untuk menangkap. Bagus! Tantangan saya berikutnya adalah bagaimana memasukkan banyak perintah flock, tetapi saya akan menempatkan itu sebagai pertanyaan terpisah. John terima kasih!
d -_- b
3
@d -_- b Saya suka nama pengguna Anda. Itu adalah username paling pintar yang pernah saya lihat.
Devyn Collier Johnson

Jawaban:

10

Pemrosesan Bash atas perintah di bawah ini mungkin mengejutkan:

flock -x -w 5 /dev/shm/counter.txt echo "4" >  /dev/shm/counter.txt && sleep 5

Bash pertama kali berjalan flock -x -w 5 /dev/shm/counter.txt echo "4" > /dev/shm/counter.txtdan, jika itu berhasil (melepaskan kunci), maka berjalan sleep 5. Dengan demikian, kunci tidak ditahan selama 5 detik yang mungkin diharapkan.

Selain &lawan&&

Jika seseorang memiliki dua perintah, Adan B, maka:

  1. A & Bdimulai Adi latar belakang dan kemudian mulai Btanpa menunggu untuk Aselesai.

  2. A && Bdimulai A, tunggu sampai selesai, dan kemudian, jika selesai dengan sukses (kode keluar 0), dimulai B. Jika Agagal (kode keluar bukan nol), maka Btidak pernah dijalankan.

Singkatnya, &dan &&dua operator daftar yang sama sekali berbeda.

John1024
sumber
3
akan mengejutkan saya jika di A && B, Aakan menunggu Bsampai selesai.
Andras Gyomrey
1
di A&& B, A dieksekusi terlebih dahulu. B dieksekusi hanya jika A dieksekusi dan keluar dengan sukses. Gunakan; B untuk selalu mengeksekusi B terlepas dari status eksekusi A.
kapad
15

Kunci file tidak wajib 1 - yaitu, Anda tidak dapat mengunci file sehingga proses lain tidak dapat mengaksesnya. Mengunci file berarti bahwa jika proses (nother) memeriksa untuk melihat apakah telah dikunci, ia akan tahu.

Tujuannya flockadalah untuk melakukan hal-hal seperti apa yang Anda inginkan, tetapi Anda kemudian harus menggunakannya flockuntuk setiap dan setiap upaya akses . Ingatlah bahwa itu memblokir panggilan; dari man flock:

jika kunci tidak dapat segera diperoleh, kawanan menunggu sampai kunci tersedia


1. Yang membuat fitur tersebut tampak tidak berguna jika Anda menggunakannya untuk, misalnya, keamanan, tetapi itu bukan tujuan dari kunci file - mereka untuk sinkronisasi, yang adalah apa yang Anda lakukan. Pengguna Leo menunjukkan bahwa mungkin ada implementasi non-standar penguncian file wajib di kernel linux ( lihat diskusi ini ), berdasarkan paralel sejarah dari sistem operasi * nix lainnya. Namun, ini tampaknya hanya antarmuka tingkat C.

goldilocks
sumber
Terima kasih! Ini membantu memahami aspek 'penasehat' dan bagaimana saya harus menggunakan flocksetiap waktu. sangat membantu!
d -_- b
2

Anda bisa menggunakan "perintah sh -c ..." untuk menjalankan seluruh perintah shell, termasuk pengalihan file, dengan kunci dipegang. Juga, karena Anda menggunakan file sebagai penghitung, Anda harus menahan kunci terus menerus saat Anda membaca dan menulis kembali. Jadi, Anda ingin melakukan sesuatu seperti ini untuk meningkatkan penghitung dan mengembalikan nilai baru:

flock --exclusive --wait 5 /dev/shm/counter.txt sh -c 'read count < /dev/shm/counter.txt ; echo $((count + 1)) > /dev/shm/counter.txt ; echo $((count + 1))'

Mengubah tanda plus ke tanda minus harus mengurangi penghitung:

flock --exclusive --wait 5 /dev/shm/counter.txt sh -c 'read count < /dev/shm/counter.txt ; echo $((count - 1)) > /dev/shm/counter.txt ; echo $((count - 1))'

Saya berharap Anda akan menginisialisasi konter sebelum pertikaian apa pun dapat terjadi, jadi tidak perlu khawatir tentang mengunci itu lebih awal:

echo 0 > /dev/shm/counter.txt

Saya tidak berpikir Anda perlu mengalahkan nilai penghitung sementara pertikaian bisa terjadi, tetapi, jika pernah melakukannya, Anda harus melakukannya dengan demikian:

flock --exclusive --wait 5 /dev/shm/counter.txt sh -c 'echo 0 > /dev/shm/counter.txt'

Saya pikir Anda mengerti cara membaca, tetapi saya memasukkannya untuk kelengkapan:

flock --shared /dev/shm/counter.txt cat /dev/shm/counter.txt
Adam Richter
sumber
Tampaknya ini adalah satu-satunya jawaban yang dengan benar memperhatikan bahwa dalam pertanyaan, file akan dibuka oleh shell bahkan sebelum kawanan berjalan ...
eichin