Atomik güncellemeler için bir dosyada özel okuma / yazma kilidi alma


10

Sayaç olarak kullanılan bir dosyaya sahip olmak istiyorum. A kullanıcısı bu numarayı yazacak ve artıracak, B kullanıcısı dosyayı okumak isteyecektir. A Kullanıcısının bu dosyayı kilitleyebilmesi mümkün mü, böylece A Kullanıcısının yazma işlemi bitene kadar kimse onu okuyamaz veya yazamaz.

Ben içine baktım flockama beklediğim gibi işe almak için görünmüyor.

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

Eğer duymak harika olurdu bu atom benzeri artan dosyayı almak için daha uygun bir yolu varsa!

Amacım:

LOCK counter.txt; write to counter.txt;

o sırada

Read counter.txt; realize it's locked so wait until that lock is finished.

1
"beklediğim gibi çalışmasını sağlayamıyor." Bu özellikle ne anlama geliyor?
John1024

Yanlış kullandığımdan eminim, ancak yukarıdaki kodu kullanırken iki kabuk kullanabilir ve bir tane kilitlediğini düşünürken ikisinin de sayaç dosyasını düzenlemesini sağlayabilirsiniz. Bu çizgiyi iki ayrı kabukta iki kez çalıştırırsam, (her biri yankı yapacak kendi numarası ile), hala ikinci sayının yazıldığını görüyorum
d -_- b

1
Birincisi kilidini tamamlayıp serbest bıraktığında, ikincisi çalışır. Bu şekilde çalışmamalı mı? (Yukarıdaki kodda , sürü kilidi serbest bıraktıktan sonra&& sleep 5 yürütülür .)
John1024

Hmm araya giriyor ... Yani bu durumda insan gözümün yakalaması çok hızlı olurdu. Harika! Bir sonraki görevim birden fazla komutun nasıl girileceği flock, ancak bunu ayrı bir soru olarak koyacağım. Teşekkürler John!
d -_- b

3
@d -_- b Kullanıcı adınızı seviyorum. Bu şimdiye kadar gördüğüm en akıllı kullanıcı adı.
Devyn Collier Johnson

Yanıtlar:


10

Bash'in aşağıdaki komutu işlemesi şaşırtıcı olabilir:

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

Bash önce çalışır flock -x -w 5 /dev/shm/counter.txt echo "4" > /dev/shm/counter.txtve bu başarılı bir şekilde tamamlanırsa (kilidi serbest bırakır), çalışır sleep 5. Bu nedenle, kilit beklenebileceği 5 saniye boyunca tutulmaz.

Bir kenara &karşı&&

Birinin iki komutu varsa Ave B:

  1. A & Bbaşlar Aarka planda ve daha sonra başlar Bbeklemeden Abitişe kadar.

  2. A && Bbaşlar A, tamamlanmasını bekler ve sonra başarıyla tamamlanırsa (çıkış kodu 0) başlar B. Eğer A(sıfırdan farklı çıkış kodu) başarısız, daha sonra Bçalıştırmak asla.

Özetle &ve &&tamamen farklı iki liste operatörüdür.


3
eğer beni şaşırtacaktı A && B, bitirmek Aiçin beklerdi B.
Andras Gyomrey

1
A && B'de önce A yürütülür. B yalnızca A başarılı bir şekilde yürütülür ve çıkılırsa yürütülür. Kullanın; B,
A.'nin

15

Dosya kilitleri zorunlu değildir 1 - Başka bir işlem böylece yani, bir dosyayı kilitleyemezsiniz olamaz erişmek. Bir dosyayı kilitlemek, (nother) bir işlemin kilitli olup olmadığını kontrol ederse bunu bileceğini gösterir.

Amacı, flockistediğiniz gibi şeyler yapmaktır, ancak daha sonra her bir erişim girişimi için kullanmanızflock gerekir . Bunların aramaları engellediğini unutmayın; from man flock:

eğer kilit hemen alınamazsa, kilit mevcut olana kadar sürü bekler


1. Bu, örneğin güvenlik için kullanıyorsanız özelliğin işe yaramaz görünmesini sağlar, ancak dosya kilitlerinin amacı bu değildir - senkronizasyon içindir, yaptığınız şey budur. Kullanıcı Leo Linux çekirdeğinde zorunlu dosya kilitleme (olmayan bir standart uygulama olabileceğini işaret bu tartışmaya bakınız diğer * Nix işletim sistemlerinden tarihsel paralellikler dayanarak). Ancak, bu yalnızca C düzeyi bir arayüz gibi görünüyor.


Teşekkürler! Bu, 'danışma' yönünü ve flockher seferinde nasıl kullanmam gerektiğini anlamama yardımcı olur . çok yararlı!
d -_- b

2

"Sh -c command ..." komutunu, dosya yönlendirmesi de dahil olmak üzere kabuk komutunun tamamını kilit basılıyken çalıştırmak için kullanabilirsiniz. Ayrıca, dosyayı sayaç olarak kullandığınız için, okuma ve geri yazma işlemi sırasında kilidi sürekli tutmanız gerekir. Böylece sayacı artırmak ve yeni değerini döndürmek için böyle bir şey yapmak istersiniz:

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))'

Artı işaretlerini eksi işaretlerine değiştirmek sayacı azaltmalıdır:

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))'

Herhangi bir çekişme gerçekleşmeden önce sayacı başlatmanızı bekliyorum, bu yüzden erken kilitleme konusunda endişelenmenize gerek yok:

echo 0 > /dev/shm/counter.txt

Çekişme yaşanırken sayaç değerini hiç düşürmeniz gerekeceğini sanmıyorum, ancak bunu yaptıysanız, bu şekilde yapmanız gerekir:

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

Sanırım okumayı nasıl yapacağınızı anlıyorsunuz, ama bütünlük için ekliyorum:

flock --shared /dev/shm/counter.txt cat /dev/shm/counter.txt

Bu görünür doğru söz konusu dosya sürüsü önce bile kabuk tarafından açılmış olur farketmedikten o tek cevap olmak çalışır ...
Eichin
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.