İnotify bir yazma başlatıldığında veya tamamlandığında bir bildirim gönderir mi?


12

Ext3 fs dosyasındaki normal bir dosya üzerinden iletişim kuran iki işlem, bir okuyucu ve bir yazar düşünün. Reader'ın IN_MODIFYdosyada bir inotify saati var. Yazar, dosyaya tek bir write()çağrıda 1000 bayt yazar . Reader inotify olayını alır fstatve dosyayı çağırır . Reader ne görür?

  1. Reader'ın st_sizedosya için en az 1000 geri alacağının garantisi var mı ? Deneylerimden öyle değil.

  2. Reader'ın aslında read()1000 bayt olabileceğine dair bir garanti var mı ?

Bu ciddi bir G / Ç bağlantılı kutuda oluyor. Örneğin, saryaklaşık 1 saniyelik bir bekleme süresini gösterir. Benim durumumda Reader, aramadan önce inotify olayını aldıktan SONRA 10 saniye bekler statve çok küçük sonuçlar alır.

Ne umuyordum inotify olay dosya hazır olana kadar teslim olmazdı. Şüphelendiğim şey, inotify olayının Yazardaki write()çağrı SIRASINDA tetiklenmesidir ve veriler hazır olduğunda sistemdeki diğer süreçler için kullanılabilir. Bu durumda, 10s yeterli zaman değildir.

Sanırım sadece çekirdeğin aslında tahmin ettiğim şekilde inotifiye ettiğini doğrulamak istiyorum. Ayrıca, muhtemelen bu davranışı değiştirmek için herhangi bir seçenek varsa?

Son olarak, bu davranış göz önüne alındığında, inotifikasyonun anlamı nedir? Olay alındıktan sonra, veriler gerçekten kullanılabilir olana kadar, dosya / dizini yoklamaya başlamış olursunuz. Bunları baştan sona yapıyor olabilir ve inotifiye etmeyi unutun.

*** DÜZENLE ** * * Tamam, sık sık olduğu gibi, gördüğüm davranış gerçekten anlamlıdır, şimdi gerçekten ne yaptığımı anlıyorum. ^ _ ^

Aslında dosyanın yaşadığı dizindeki bir IN_CREATE olayına yanıt veriyorum. Bu yüzden aslında stat () 'ın dosyanın oluşturulmasına yanıt olarak, daha sonra gelen IN_MODIFY olay, ille ki mutlaka değilim.

Kodumu değiştireceğim, böylece IN_CREATE olayı aldığımda, dosyanın kendisinde IN_MODIFY abone olacağım ve IN_MODIFY olayını alana kadar dosyayı okumaya çalışmayacağım. Orada dosyaya bir yazma özledim olabilir küçük bir pencere olduğunu fark, ama bu benim uygulama için kabul edilebilir, çünkü en kötü durumda, dosya maksimum birkaç saniye sonra kapatılacaktır.


Dosya yerine pipo kullanabilirsiniz. Görmek adam mknod
daniel kullmann

İki işlem arasında çok terabaytlık bir arabellek olması için düzenli bir dosya kullanmamız gerekir. Ayrıca yeniden başlatma boyunca arabellekteki verileri korumak için.
Todd

Yanıtlar:


5

Çekirdek kaynağında gördüğüm kadarıyla , inotify sadece bir yazma tamamlandıktan sonra patlar (yani tahmininiz yanlıştır). Bildirim tetiklendikten sonra, sistem aramasını sys_writeuygulayan fonksiyonda sadece iki şey daha olur write: bazı zamanlayıcı parametreleri ayarlama ve dosya tanımlayıcıdaki konumu güncelleme. Bu kod 2.6.14'e kadar benzerdir . Bildirim tetiklendiğinde, dosyanın zaten yeni boyutu vardır.

Yanlış gidebilecek şeyleri kontrol edin:

  • Belki de okuyucu önceki yazıdan eski bildirimler alıyor.
  • Okuyucu arar statve sonra arar readveya tersi yaparsa, aralarında bir şey olabilir. Dosyaya eklemeye devam ederseniz, statönce arama, o kadar okuyabileceğinizi garanti eder, ancak readhenüz inotify bildirimi almamış olsa bile , okuyucunun çağrılmasıyla daha fazla veri yazılmış olabilir.
  • Yazarın aramaları write, çekirdeğin istenen sayıda karakter yazacağı anlamına gelmez. Atomik yazıların herhangi bir boyuta kadar garanti edildiği çok az durum vardır. writeBununla birlikte, her çağrı atomik olarak garanti edilir: bir noktada veriler henüz yazılmamıştır ve daha sonra aniden n bayt yazılmıştır, burada nwrite çağrının dönüş değeridir . Kısmen yazılmış bir dosyayı gözlemlerseniz, bunun writeboyut bağımsız değişkeninden daha az döndürdüğü anlamına gelir .

Neler olup bittiğini araştırmak için yararlı araçlar şunları içerir:

  • strace -tt
  • denetim alt sistemi

fikirler için teşekkür ederiz. Ben sadece kodu inceledim ve aslında sadece -1 hata durumu için yazma dönüş değeri olarak kontrol ediyorum. Yani, tüm verilerin yazıldığını gösteren dönüş değerini yazmadan alamıyor olabilirim. Yine de, dosyaya aslında baktıktan sonra, tüm "1000" baytların aslında yazıldığını biliyorum, çünkü dosya iyi durumda, yani bütün, tutarlı kayıtlardan oluşuyor. Yani ilk kayıt kısmen yazılmıyor.
Todd
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.