Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Bu makale, G/Ç için varsayılan davranışın zaman uyumlu olmasına rağmen zaman uyumsuz olarak görünmesi sorununu çözmenize yardımcı olur.
Özgün ürün sürümü: Windows
Özgün KB numarası: 156932
Özet
Microsoft Windows'ta dosya giriş/çıkışı (G/Ç), senkron veya asenkron olabilir. G/Ç için varsayılan davranış eşzamanlıdır; burada G/Ç işlevi çağrılır ve G/Ç tamamlandığında geri döner. Asenkron G/Ç, bir G/Ç işlevinin yürütmeyi çağırana hemen geri döndürmesine izin verir, ancak G/Ç'nin tamamlanmış sayılması gelecekteki bir zamana kadar beklenmez. İşletim sistemi, G/Ç tamamlandığında çağıranı bilgilendirir. Bunun yerine çağıran, işletim sisteminin hizmetlerini kullanarak bekleyen G/Ç işleminin durumunu belirleyebilir.
Zaman uyumsuz G/Ç'nin avantajı, G/Ç işlemi tamamlanırken çağıranın başka işler yapmak veya daha fazla istek göndermek için zamanı olmasıdır. Çakışan G/Ç terimi, genellikle Zaman Uyumsuz G/Ç için, Çakışmayan G/Ç terimi ise Zaman Uyumlu G/Ç için kullanılır. Bu makalede G/Ç işlemleri için Asenkron ve Senkron terimleri kullanılır. Bu makalede, okuyucunun , , CreateFile
ReadFile
gibi WriteFile
Dosya G/Ç işlevleri hakkında bilgi sahibi olduğu varsayılır.
Sık sık, zaman uyumsuz G/Ç işlemleri tıpkı senkron G/Ç gibi davranır. Bu makalenin sonraki bölümlerde ele aldığı ve G/Ç işlemlerinin zaman uyumlu bir şekilde tamamlanmasını sağlayan bazı koşullar. G/Ç işlevleri G/Ç tamamlanana kadar geri dönmediğinden, çağıranın arka plan işlemlerine ayıracak zamanı yok.
Zaman uyumlu ve zaman uyumsuz G/Ç ile ilgili çeşitli işlevler vardır. Bu makalede ReadFile
ve WriteFile
örnek olarak kullanılır. İyi alternatifler ReadFileEx
ve WriteFileEx
olacaktır. Bu makalede özellikle yalnızca disk G/Ç'leri ele alınsa da, ilkelerin çoğu seri G/Ç veya ağ G/Ç gibi diğer G/Ç türlerine uygulanabilir.
Eşzamansız G/Ç ayarla
Dosya açıldığında FILE_FLAG_OVERLAPPED
bayrağı CreateFile
belirtilmelidir. Bu bayrak, dosyadaki G/Ç işlemlerinin zaman uyumsuz olarak gerçekleştirilmesini sağlar. Örnek aşağıda verilmiştir:
HANDLE hFile;
hFile = CreateFile(szFileName,
GENERIC_READ,
0,
NULL,
OPEN_EXISTING,
FILE_FLAG_NORMAL | FILE_FLAG_OVERLAPPED,
NULL);
if (hFile == INVALID_HANDLE_VALUE)
ErrorOpeningFile();
Zaman uyumsuz G/Ç için kodlarken dikkatli olun çünkü sistem gerektiğinde bir işlemi zaman uyumlu yapma hakkını saklıdır. Programı, senkron veya asenkron olarak tamamlanabilecek bir G/Ç işlemini doğru şekilde işlemek üzere yazmanız en iyisidir. Örnek kodda bu önemli nokta gösterilmektedir.
Ek işlemleri kuyruğa alma veya arka plan çalışması yapma gibi zaman uyumsuz işlemlerin tamamlanmasını beklerken bir programın gerçekleştirebileceği birçok şey vardır. Örneğin, aşağıdaki kod bir okuma işleminin çakışan ve çakışmayan tamamlanmasını düzgün bir şekilde işler. Henüz tamamlanmamış G/Ç'nin tamamlanmasını beklemekten başka bir şey yapmaz.
if (!ReadFile(hFile,
pDataBuf,
dwSizeOfBuffer,
&NumberOfBytesRead,
&osReadOperation )
{
if (GetLastError() != ERROR_IO_PENDING)
{
// Some other error occurred while reading the file.
ErrorReadingFile();
ExitProcess(0);
}
else
// Operation has been queued and
// will complete in the future.
fOverlapped = TRUE;
}
else
// Operation has completed immediately.
fOverlapped = FALSE;
if (fOverlapped)
{
// Wait for the operation to complete before continuing.
// You could do some background work if you wanted to.
if (GetOverlappedResult( hFile,
&osReadOperation,
&NumberOfBytesTransferred,
TRUE))
ReadHasCompleted(NumberOfBytesTransferred);
else
// Operation has completed, but it failed.
ErrorReadingFile();
}
else
ReadHasCompleted(NumberOfBytesRead);
Not
&NumberOfBytesRead
içine geçirilen ReadFile
, &NumberOfBytesTransferred
içine geçirilen GetOverlappedResult
'ten farklıdır. Bir işlem zaman uyumsuz hale getirildiyse, GetOverlappedResult
işlem tamamlandıktan sonra işlemde aktarılan gerçek bayt sayısını belirlemek için kullanılır.
&NumberOfBytesRead
'dan ReadFile
içine geçirilenler anlamsızdır.
Öte yandan, bir işlem hemen tamamlanırsa, &NumberOfBytesRead
öğesi, ReadFile
içine iletildiğinde okunan bayt sayısı için geçerlidir. Bu durumda, OVERLAPPED
içine geçirilen yapıyı yoksayın; ReadFile
ile GetOverlappedResult
veya WaitForSingleObject
kullanmayın.
Zaman uyumsuz operasyonla ilgili bir diğer uyarı, bekleyen operasyon tamamlanana kadar bir OVERLAPPED
yapısı kullanmamanız gerektiğidir. Başka bir deyişle, bekleyen üç G/Ç işleminiz varsa üç OVERLAPPED
yapı kullanmanız gerekir. Bir OVERLAPPED
yapıyı yeniden kullanırsanız G/Ç işlemlerinde tahmin edilemeyen sonuçlar alırsınız ve veri bozulmasıyla karşılaşabilirsiniz. Ayrıca, bir yapıyı ilk kez kullanabilmeniz için veya önceki bir OVERLAPPED
işlem tamamlandıktan sonra yeniden kullanmadan önce, yeni işlemi hiçbir artık verinin etkilememesi için doğru şekilde başlatmanız gerekir.
Aynı kısıtlama türü, bir işlemde kullanılan veri arabelleği için de geçerlidir. Veri arabelleği ilgili G/Ç işlemi tamamlanana kadar okunmamalı veya yazılmamalıdır; arabelleği okumak veya yazmak hatalara ve bozuk verilere neden olabilir.
Asenkron G/Ç hala senkron görünüyor
Ancak bu makalenin önceki bölümlerindeki yönergeleri izlediyseniz, tüm G/Ç işlemleriniz verilen sırayla hâlâ genellikle zaman uyumlu olarak tamamlanmaktadır ve hiçbir ReadFile
işlemi False döndürmez, bu da arka plan çalışması için hiçbir zamanınız olmadığı anlamına gelir. Bu neden oluşur?
Zaman uyumsuz işlem için kodlamış olsanız bile G/Ç işlemlerinin zaman uyumlu bir şekilde tamamlanmasının çeşitli nedenleri vardır.
Sıkıştırma
Zaman uyumsuz işleme yönelik bir engel, Yeni Teknoloji Dosya Sistemi (NTFS) sıkıştırmasıdır. Dosya sistemi sürücüsü zaman uyumsuz olarak sıkıştırılmış dosyalara erişmeyecek; bunun yerine tüm işlemler zaman uyumlu hale getirilir. Bu engelleme, COMPRESS veya PKZIP'ye benzer yardımcı programlarla sıkıştırılmış dosyalar için geçerli değildir.
NTFS şifrelemesi
Sıkıştırmaya benzer şekilde, dosya şifrelemesi de sistem sürücüsünün zaman uyumsuz G/Ç'yi zaman uyumluya dönüştürmesine neden olur. Dosyaların şifresi çözülürse G/Ç istekleri eşzamansız olur.
Dosyayı genişletme
G/Ç işlemlerinin zaman uyumlu bir şekilde tamamlanmasının bir diğer nedeni de işlemlerin kendileridir. Windows'da, uzunluğunu genişleten bir dosyaya yapılan tüm yazma işlemleri eşzamanlı olur.
Not
Uygulamalar, daha önce bahsedilen yazma işlemini zaman uyumsuz hale getirmek için işlevini kullanarak SetFileValidData
dosyanın Geçerli Veri Uzunluğunu değiştirebilir ve ardından bir WriteFile
verebilir.
SetFileValidData
kullanarak (Windows XP ve sonraki sürümlerde kullanılabilir), uygulamalar dosyaları sıfırla doldurma için performans cezasına neden olmadan verimli bir şekilde genişletebilir.
NTFS dosya sistemi tarafından SetFileValidData
tanımlanan geçerli veri uzunluğuna (VDL) kadar verileri sıfırdan doldurmadığından, bu işlevin, dosyanın daha önce diğer dosyalar tarafından kaplanmış kümelere atanabileceği güvenlik etkileri vardır. Bu nedenle, SetFileValidData
çağıranın yeni SeManageVolumePrivilege
etkin olmasını gerektirir (varsayılan olarak, bu yalnızca yöneticilere atanır). Microsoft, bağımsız yazılım satıcılarının (ISV) bu işlevi kullanmanın etkilerini dikkatle değerlendirmesini önerir.
Önbellek
Çoğu G/Ç sürücüsünün (disk, iletişim ve diğerleri) özel durum kodu vardır. Burada bir G/Ç isteği hemen tamamlanabilirse işlem tamamlanır ve ReadFile
veya WriteFile
işlevi TRUE döndürür. Her şekilde, bu tür işlemler zaman uyumlu olarak görünür. Disk cihazı için genellikle veriler bellekte önbelleğe alınırken bir G/Ç isteği hemen tamamlanabilir.
Veriler önbellekte değil
Ancak, veriler önbellekte değilse önbellek düzeni size karşı çalışabilir. Windows önbelleği, dosya eşlemeleri kullanılarak dahili olarak uygulanır. Windows'daki bellek yöneticisi, önbellek yöneticisi tarafından kullanılan dosya eşlemelerini yönetmek için zaman uyumsuz bir sayfa hata mekanizması sağlamaz. Önbellek yöneticisi, istenen sayfanın bellekte olup olmadığını doğrulayabilir, dolayısıyla zaman uyumsuz önbelleğe alınmış bir okuma gönderirseniz ve sayfalar bellekte değilse, dosya sistemi sürücüsü iş parçacığınızın engellenmesini istemediğinizi varsayar ve istek sınırlı bir çalışan iş parçacığı havuzu tarafından işlenir. Çağrınızdan ReadFile
sonra, okuma hala beklemede iken denetim programınıza döndürülür.
Bu, az sayıda istek için düzgün çalışır, ancak çalışan iş parçacığı havuzu sınırlı olduğundan (şu anda 16 MB'lık bir sistemde üç tane), disk sürücüsüne belirli bir zamanda yalnızca birkaç istek kuyruğa alınır. Önbellekte olmayan veriler için çok sayıda G/Ç işlemi yaparsanız, önbellek yöneticisi ve bellek yöneticisi doygun hale gelir ve istekleriniz zaman uyumlu hale gelir.
Önbellek yöneticisinin davranışı, bir dosyaya sırayla mı yoksa rastgele mi erişdiğinize bağlı olarak da etkilenebilir. Önbellek avantajları en çok dosyalara sırayla erişirken görülür.
FILE_FLAG_SEQUENTIAL_SCAN
Çağrıdaki CreateFile
bayrak, önbelleği bu erişim türü için en iyi duruma getirecektir. Ancak, dosyalara rastgele bir şekilde erişiyorsanız, önbellek yöneticisinin bu tür erişim için davranışını optimize etmesini sağlamak amacıyla FILE_FLAG_RANDOM_ACCESS
içindeki CreateFile
bayrağını kullanın.
Önbelleği kullanma
FILE_FLAG_NO_BUFFERING
bayrağı, asenkron işlem için dosya sisteminin davranışı üzerinde en fazla etkiye sahiptir. G/Ç isteklerinin asenkron olmasını garanti etmenin en iyi yoludur. Dosya sistemine hiç önbellek mekanizması kullanmamasını belirtir.
Not
Bu bayrağı kullanmanın veri arabelleği hizalaması ve cihazın kesim boyutuyla ilgili bazı kısıtlamaları vardır. Daha fazla bilgi için CreateFile işlevinin bu bayrağı düzgün kullanma hakkındaki belgelerindeki işlev başvurusuna bakın.
Gerçek dünya test sonuçları
Aşağıda örnek koddan bazı test sonuçları verilmiştir. Sayıların büyüklüğü burada önemli değildir ve bilgisayardan bilgisayara farklılık gösterir, ancak sayıların birbirine göre ilişkisi bayrakların performans üzerindeki genel etkisini aydınlatmaktadır.
Aşağıdakilerden birine benzer sonuçlar görmeyi bekleyebilirsiniz:
Test 1
Asynchronous, unbuffered I/O: asynchio /f*.dat /n Operations completed out of the order in which they were requested. 500 requests queued in 0.224264 second. 500 requests completed in 4.982481 seconds.
Bu test, daha önce bahsedilen programın hızlı bir şekilde 500 G/Ç isteği yayımladığını ve diğer işleri yapmak veya daha fazla istek göndermek için çok fazla zamanı olduğunu gösterir.
Test 2
Synchronous, unbuffered I/O: asynchio /f*.dat /s /n Operations completed in the order issued. 500 requests queued and completed in 4.495806 seconds.
Bu test, bu programın işlemlerini tamamlamak için ReadFile'ı çağırmak için 4,495880 saniye harcadığını, ancak test 1'in aynı istekleri göndermek için yalnızca 0,224264 saniye harcadığını gösterir. Test 2'de, programın herhangi bir arka plan çalışması yapması için fazladan zaman yoktu.
Test 3
Asynchronous, buffered I/O: asynchio /f*.dat Operations completed in the order issued. 500 requests issued and completed in 0.251670 second.
Bu test önbelleğin zaman uyumlu doğasını gösterir. Tüm okumalar 0,251670 saniye içinde verildi ve tamamlandı. Başka bir deyişle, eşzamansız istekler eşzamanlı olarak tamamlandı. Bu test, veriler önbellekte olduğunda önbellek yöneticisinin yüksek performansını da gösterir.
Test 4
Synchronous, buffered I/O: asynchio /f*.dat /s Operations completed in the order issued. 500 requests and completed in 0.217011 seconds.
Bu test, 3. testle aynı sonuçları gösterir. Önbellekten eşzamanlı okumalar, önbellekten eşzamansız okuma işleminden biraz daha hızlı tamamlanır. Bu test, veriler önbellekte olduğunda önbellek yöneticisinin yüksek performansını da gösterir.
Sonuç
Hangi yöntemin en iyi olduğuna karar vekleyebilirsiniz çünkü her şey programınızın gerçekleştirdiği işlemlerin türüne, boyutuna ve sayısına bağlıdır.
CreateFile
için özel bayrak belirtilmediğinde varsayılan dosya erişimi, zaman uyumlu ve önbelleğe alınmış bir işlemdir.
Not
Dosya sistemi sürücüsü, öngörüye dayalı zaman uyumsuz ileri okuma ve değiştirilmiş verilerin zaman uyumsuz gecikmeli yazmasını gerçekleştirdiğinden, bu modda bazı otomatik zaman uyumsuz davranışlar elde edersiniz. Bu davranış uygulamanın G/Ç'sini zaman uyumsuz hale getirmese de, basit uygulamaların büyük çoğunluğu için ideal bir durumdur.
Öte yandan, uygulamanız basit değilse, bu makalenin önceki bölümlerinde gösterilen testlere benzer şekilde en iyi yöntemi belirlemek için profil oluşturma ve performans izleme yapmanız gerekebilir. veya ReadFile
işlevinde harcanan sürenin WriteFile
profilini oluşturmak ve bu süreyi gerçek G/Ç işlemlerinin tamamlanmasının ne kadar süreceğiyle karşılaştırmak yararlı olur. Çoğu zaman I/O işleminin gerçekleştirilmesi için harcanıyorsa, G/Ç'niz eşzamanlı olarak tamamlanıyor demektir. Ancak G/Ç isteklerinin verilmesi için harcanan süre G/Ç işlemlerinin tamamlanması için geçen süreye kıyasla nispeten küçükse, işlemleriniz zaman uyumsuz olarak ele alınır. Bu makalede daha önce bahsedilen örnek kod, kendi iç profil oluşturma işlemini gerçekleştirmek için işlevini kullanır QueryPerformanceCounter
.
Performans izleme, programınızın diski ve önbelleği ne kadar verimli kullandığını belirlemeye yardımcı olabilir. Cache nesnesi için performans sayaçlarından herhangi birinin izlenmesi önbellek yöneticisinin performansını gösterir. Fiziksel Disk veya Mantıksal Disk nesneleri için performans sayaçlarının izlenmesi disk sistemlerinin performansını gösterir.
Performans izleme konusunda yardımcı olan çeşitli yardımcı programlar vardır.
PerfMon
ve DiskPerf
özellikle yararlıdır. Sistemin disk sistemlerinin performansıyla ilgili veri toplaması için önce DiskPerf
komutunu vermelisiniz. Komutu verdikten sonra, veri toplamayı başlatmak için sistemi yeniden başlatmanız gerekir.