G/Ç tamamlama portları

G/Ç tamamlama bağlantı noktaları, çok işlemcili bir sistemde birden çok eşzamansız G/Ç isteğinin işlenmesi için verimli bir iş parçacığı modeli sunar. Bir işlem G/Ç tamamlama bağlantı noktası oluşturduğunda, sistem tek amacı bu isteklere hizmet vermek olan iş parçacıkları için ilişkili bir kuyruk nesnesi oluşturur. Birçok eşzamanlı zaman uyumsuz G/Ç isteğini işleyen işlemler, G/Ç tamamlama bağlantı noktalarını önceden ayrılmış bir iş parçacığı havuzuyla birlikte kullanarak, G/Ç isteği aldıklarında iş parçacıkları oluşturmaktan daha hızlı ve verimli bir şekilde bunu yapabilir.

G/Ç tamamlama bağlantı noktaları ne zaman kullanılır?

Scenario Önerilen yaklaşım
Yüzlerce/binlerce eşzamanlı bağlantıyı işleyen yüksek performanslı sunucu G/Ç tamamlama bağlantı noktaları — bunun için özel olarak tasarlanmıştır. Çekirdek, IŞ parçacığı zamanlamasını CPU eşzamanlılığıyla eşleşecek şekilde yönetir.
Orta düzey eşzamanlılık (onlarca asenkron işlem) İş parçacığı havuzu G/Ç işlemleri (CreateThreadpoolIo) — daha basit API, IOCP’yi dahili olarak kendisi yönetir. Manuel iş parçacığı denetimi gerektirmeyen yeni kodlarda bunu tercih edin.
Modern C++'ta basit eşzamansız dosya işlemleri Özel bir IOCP dağıtıcısıyla C++20 eş yordamları veya FileStream ile async/await .NET.
Tek iş parçacıklı veya düşük hacimli G/Ç Eşzamanlı G/Ç veya olay sinyallemeli basit örtüşmeli G/Ç. IOCP, tek akışlı senaryolar için gereksiz karmaşıklık ekler.

Not

İş parçacığı havuzu API'sinin ham IOCP'ye karşı: Windows iş parçacığı havuzu API'si (CreateThreadpoolIo, StartThreadpoolIo) IOCP'yi dahili olarak kullanır ancak iş parçacığı yaşam döngüsü yönetimini otomatik olarak işler. Yeni sunucu uygulamaları için önce iş parçacığı havuzu API'sini göz önünde bulundurun; daha az ortak kodla aynı ölçeklenebilirliği sağlar. Tamamlama bağlantı noktasının eşzamanlılık değeri veya özel iş parçacığı yönetimi üzerinde açık denetime ihtiyacınız olduğunda ham IOCP kullanın.

G/Ç tamamlama portları nasıl çalışır?

CreateIoCompletionPort işlevi bir G/Ç tamamlama bağlantı noktası oluşturur ve bir veya daha fazla dosya tutamacını bu bağlantı noktasıyla ilişkilendirir. Bu dosya tanıtıcılarından birindeki eşzamansız bir G/Ç işlemi tamamlandığında, ilişkili G/Ç tamamlama portuna ilk giren ilk çıkar (FIFO) sırasına göre bir G/Ç tamamlama paketi kuyruğa alınır. Bu mekanizmanın güçlü kullanımlarından biri, birden çok dosya tutamacı için eşitleme noktasını tek bir nesnede birleştirmektir, ancak başka yararlı uygulamalar da vardır. Lütfen paketlerin FIFO sırasına göre kuyruğa alınsalar da kuyruktan farklı bir sırada çıkarılabileceklerini unutmayın.

Not

Burada kullanılan dosya tanıtıcısı terimi, yalnızca disk üzerindeki bir dosyayı değil çakışan G/Ç uç noktasını temsil eden bir sistem soyutlaması anlamına gelir. Örneğin, bir ağ uç noktası, TCP yuvası, adlandırılmış kanal veya posta yuvası olabilir. Çakışan G/Ç'leri destekleyen tüm sistem nesneleri kullanılabilir. İlgili G/Ç işlevlerinin listesi için bu konunun sonuna bakın.

Bir dosya tanıtıcısı bir tamamlama kapısıyla ilişkilendirildiğinde, paketin tamamlama kapısından kaldırılmasına kadar sağlanan durum bloğu güncelleştirilmez. Tek istisna, orijinal işlemin bir hatayla eşzamanlı olarak dönmesi durumudur. Bir iş parçacığı (ana iş parçacığının oluşturduğu bir iş parçacığı veya ana iş parçacığının kendisi), doğrudan eşzamansız G/Ç işleminin tamamlanmasını beklemek yerine, bir tamamlama paketinin G/Ç tamamlama bağlantı noktasına kuyruğa eklenmesini beklemek için GetQueuedCompletionStatus işlevini kullanır. G/Ç tamamlama bağlantı noktası üzerinde yürütmelerini engelleyen iş parçacıkları, ilk giren son çıkış (LIFO) sırasında serbest bırakılır ve sonraki tamamlama paketi bu iş parçacığı için G/Ç tamamlama bağlantı noktasının FIFO kuyruğundan alınır. Bu, bir tamamlama paketinin bir iş parçacığına iletilmesi durumunda, sistemin bu bağlantı noktasıyla ilişkili olan son (en son) iş parçacığını serbest bırakıp en eski G/Ç tamamlamasına ait tamamlama bilgilerini ona geçirdiği anlamına gelir.

Belirtilen G/Ç tamamlama bağlantı noktası için herhangi bir sayıda iş parçacığı GetQueuedCompletionStatus'u çağırabilse de, belirtilen bir iş parçacığı GetQueuedCompletionStatus'u ilk kez çağırdığında, üç şeyden biri gerçekleşene kadar belirtilen G/Ç tamamlama bağlantı noktasıyla ilişkilendirilir: İş parçacığından çıkılır, farklı bir G/Ç tamamlama bağlantı noktası belirtilir veya G/Ç tamamlama bağlantı noktası kapatılır. Başka bir deyişle, tek bir iş parçacığı en fazla bir G/Ç tamamlama bağlantı noktasıyla ilişkilendirilebilir.

Bir tamamlama paketi G/Ç tamamlama bağlantı noktasına kuyruğa alındığında, sistem önce bu bağlantı noktasıyla ilişkili kaç iş parçacığının çalıştığını denetler. Çalışan iş parçacığı sayısı eşzamanlılık değerinden küçükse (sonraki bölümde anlatılacaktır), bekleyen iş parçacıklarından birinin (en son) tamamlama paketini işlemesine izin verilir. Çalışan bir iş parçacığı işlemeyi tamamladığında, genellikle GetQueuedCompletionStatus'ı yeniden çağırır; bu noktada bir sonraki tamamlama paketiyle birlikte döndürür veya kuyruk boşsa bekler.

İş parçacıkları, tamamlama paketlerini bir G/Ç tamamlama bağlantı noktasının kuyruğuna yerleştirmek için PostQueuedCompletionStatus işlevini kullanabilir. Bunu yaptığınızda, tamamlama bağlantı noktası, G/Ç sisteminden G/Ç tamamlama paketlerini almanın yanı sıra işlemin diğer iş parçacıklarından gelen iletişimleri almak için de kullanılabilir. PostQueuedCompletionStatus işlevi, bir uygulamanın zaman uyumsuz G/Ç işlemi başlatmadan kendi özel amaçlı tamamlama paketlerini G/Ç tamamlama bağlantı noktasına kuyruğa almalarını sağlar. Bu, örneğin dış olayları çalışan iş parçacıklarına bildirmek için yararlıdır.

G/Ç tamamlama bağlantı noktası tanıtıcısı ve bu belirli G/Ç tamamlama bağlantı noktasıyla ilişkilendirilmiş her dosya tanıtıcısı, G/Ç tamamlama bağlantı noktasına başvurular olarak bilinir. G/Ç tamamlama bağlantı noktası, artık ona yönelik hiçbir referans kalmadığında serbest bırakılır. Bu nedenle, G/Ç tamamlama bağlantı noktasını ve ilişkili sistem kaynaklarını serbest bırakmak için bu tanıtıcıların tümü düzgün bir şekilde kapatılmalıdır. Bu koşullar karşılandıktan sonra, bir uygulamanın CloseHandle işlevini çağırarak G/Ç tamamlama bağlantı noktası tutamacını kapatması gerekir.

Not

Bir G/Ç tamamlama kapısı, onu oluşturan işlemle ilişkilidir ve işlemler arasında paylaşılamaz. Ancak, tek bir tanıtıcı aynı işlem içindeki iş parçacıkları arasında paylaşılabilir.

İş Parçacıkları ve Eşzamanlılık

Bir G/Ç tamamlama bağlantı noktasının dikkatle dikkate alınması gereken en önemli özelliği eşzamanlılık değeridir. Tamamlanma bağlantı noktasının eşzamanlılık değeri, NumberOfConcurrentThreads parametresi aracılığıyla CreateIoCompletionPort ile oluşturulduğunda belirtilir. Bu değer, tamamlanma bağlantı noktasıyla ilişkili çalıştırılabilir iş parçacığı sayısını sınırlar. Tamamlanma bağlantı noktasıyla ilişkili çalıştırılabilir iş parçacıklarının toplam sayısı eşzamanlılık değerine ulaştığında, çalıştırılabilir iş parçacıklarının sayısı eşzamanlılık değerinin altına düşene kadar sistem bu tamamlama bağlantı noktasıyla ilişkili sonraki iş parçacıklarının yürütülmesini engeller.

En verimli senaryo, kuyrukta bekleyen tamamlama paketleri olduğunda gerçekleşir, ancak bağlantı noktası eşzamanlılık sınırına ulaştığından hiçbir bekleme gerçekleşemez. GetQueuedCompletionStatus işlev çağrısında bekleyen bir ve birden çok iş parçacığının eşzamanlılık değeriyle ne olduğunu düşünün. Bu durumda, kuyrukta her zaman bekleyen tamamlama paketleri varsa, çalışan iş parçacığı GetQueuedCompletionStatus çağrısını yaptığında, daha önce belirtildiği gibi iş parçacığı kuyruğu LIFO olduğundan yürütmeyi bloklamaz. Bunun yerine, bu iş parçacığı kuyruktaki bir sonraki tamamlama paketini hemen işlemeye başlar. İş parçacığı bağlam değişimleri meydana gelmez; çünkü çalışan iş parçacığı tamamlama paketlerini sürekli almaya devam eder ve diğer iş parçacıkları çalışamaz.

Not

Önceki örnekte, ek iş parçacıkları gereksizmiş ve hiç çalışmazmış gibi görünür; ancak bu, çalışan iş parçacığının başka bir mekanizma tarafından hiçbir zaman bekleme durumuna geçirilmediği, sonlanmadığı veya ilişkili G/Ç tamamlama bağlantı noktasını başka bir şekilde kapatmadığı varsayımına dayanır. Uygulamayı tasarlarken bu tür iş parçacığı yürütmenin tüm sonuçlarına dikkat edin.

Eşzamanlılık değeri için seçecek en iyi genel maksimum değer, bilgisayardaki CPU sayısıdır. İşleminiz uzun bir hesaplama gerektiriyorsa, daha büyük bir eşzamanlılık değeri daha fazla iş parçacığının çalışmasına izin verir. Her tamamlama paketinin tamamlanması daha uzun sürebilir, ancak aynı anda daha fazla tamamlama paketi işlenir. Uygulamanız için en iyi etkiyi elde etmek için profil oluşturma araçlarıyla birlikte eşzamanlılık değeriyle denemeler yapabilirsiniz.

Sistem ayrıca GetQueuedCompletionStatus'ta bekleyen bir iş parçacığının, aynı G/Ç tamamlama bağlantı noktasıyla ilişkilendirilmiş başka bir çalışan iş parçacığının başka nedenlerle bekleme durumuna girmesi durumunda (örneğin SuspendThread işlevi) bir tamamlama paketini işlemesine izin verir. Bekleme durumundaki iş parçacığı yeniden çalışmaya başladığında, etkin iş parçacığı sayısının eşzamanlılık değerini aştığı kısa bir süre olabilir. Ancak sistem, etkin iş parçacıklarının sayısı eşzamanlılık değerinin altına düşene kadar yeni etkin iş parçacıklarına izin vermeyerek bu sayıyı hızla azaltır. Bu, uygulamanızın iş parçacığı havuzunda eşzamanlılık değerinden daha fazla iş parçacığı oluşturmasını sağlamak için bir nedendir. İş parçacığı havuzu yönetimi bu konunun kapsamı dışındadır, ancak iş parçacığı havuzunda sistemdeki işlemcilerin en az iki katı iş parçacığı olması iyi bir kuraldır. İş parçacığı havuzları hakkında ek bilgi için bkz. İş Parçacığı Havuzları.

Desteklenen G/Ç İşlevleri

G/Ç tamamlama bağlantı noktaları kullanılarak tamamlanan G/Ç işlemlerini başlatmak için aşağıdaki işlevler kullanılabilir. G/Ç tamamlama bağlantı noktası mekanizmasını etkinleştirmek için işleve daha önce G/Ç tamamlama bağlantı noktasıyla ilişkilendirilmiş bir OVERLAPPED yapısının bir örneğini ve bir dosya tanıtıcısını (CreateIoCompletionPort çağrısıyla) geçirmeniz gerekir:

İşlemler ve İş Parçacıkları Hakkında

BindIoCompletionCallback

CreateIoCompletionPort