Bir iplik ve elyaf arasındaki fark nedir?


187

Bir iplik ve elyaf arasındaki fark nedir? Ruby'den gelen lifleri duydum ve diğer dillerde mevcut olduklarını duydum, biri bana bir iplik ve lif arasındaki farkın ne olduğunu basit bir şekilde açıklayabilir.

Yanıtlar:


163

En basit terimlerle, iplikler genellikle önleyici olarak kabul edilirler (işletim sistemine bağlı olarak bu her zaman doğru olmayabilir), ancak lifler hafif, kooperatif iplikler olarak kabul edilir. Her ikisi de uygulamanız için ayrı yürütme yollarıdır.

Konu ile: geçerli yürütme yolu herhangi bir zamanda kesilebilir veya önlenebilir (not: bu ifade bir genellemedir ve OS / iş parçacığı paketine / vb. Bağlı olarak her zaman doğru olmayabilir). Bu, iş parçacığı için veri bütünlüğünün büyük bir sorun olduğu anlamına gelir, çünkü bir iş parçacığı bir veri parçasını güncellemenin ortasında durdurulabilir ve verilerin bütünlüğünü kötü veya eksik durumda bırakır. Bu aynı zamanda işletim sisteminin aynı anda birden fazla iş parçacığı çalıştırarak ve veri erişimini korumak için geliştiriciye bırakarak birden fazla CPU ve CPU çekirdeğinden yararlanabileceği anlamına gelir.

Fiberlerle: geçerli yürütme yolu sadece fiber yürütme verdiğinde kesilir (yukarıdakiyle aynı not). Bu, liflerin her zaman iyi tanımlanmış yerlerde başlayıp durduğu anlamına gelir, bu nedenle veri bütünlüğü çok daha az sorun olur. Ayrıca, fiberler genellikle kullanıcı alanında yönetildiği için, pahalı bağlam anahtarları ve CPU durumu değişikliklerine gerek yoktur, bu da bir fiberden diğerine geçişi son derece verimli hale getirir. Öte yandan, hiçbir iki fiber tam olarak aynı anda çalışamayacağından, sadece fiberleri kullanmak birden fazla CPU veya birden fazla CPU çekirdeğinden faydalanmayacaktır.


7
Lifleri paralel olarak yürütmek için birden fazla iplik kullanmanın bir yolu var mı?
Baradé

2
@Jason, "liflerle ~" ifadesini kullandığınızda, geçerli yürütme yolu yalnızca fiber yürütme verdiğinde kesilir "ve" fiberler her zaman iyi tanımlanmış yerlerde başlar ve durur, böylece veri bütünlüğü çok daha az sorun olur ", Yani Değişkenleri paylaşırken "kilitleme mekanizmaları" ve değişken değişkenler kullanmamız gerekmez mi? Yoksa hala böyle şeyler yapmamız gerektiği anlamına mı geliyor?
Pacerier

@ Baradé Bu ilginç bir soru, bir cevap buldunuz mu?
Mayur

57

İplikler önleyici zamanlama kullanır, lifler ise kooperatif kullanır çizelgeleme .

Bir iplik ile, kontrol akışı herhangi bir zamanda kesintiye uğrayabilir ve başka bir iplik devralabilir. Birden fazla işlemciyle, aynı anda birden çok iş parçacığına sahip olabilirsiniz ( eşzamanlı çoklu iş parçacığı veya SMT). Sonuç olarak, çok eşzamanlı veri erişimi dikkatli ve verilerinizi muteksler, semaforlar, koşul değişkenleri vb. İle korumanız gerekir. Doğru olmak genellikle çok zor.

Bir fiber ile kontrol sadece söylediğinizde, tipik olarak benzer bir adla adlandırılan bir işlev çağrısıyla değişir yield(). Bu, veri yapılarının veya mutekslerin atomisitesi hakkında endişelenmenize gerek olmadığından, eşzamanlı veri erişimini kolaylaştırır. Vermediğin sürece, korunma tehlikesi yok ve üzerinde çalıştığınız verileri okumaya veya değiştirmeye çalışan başka bir lif bulundurma . Sonuç olarak, eğer lifiniz sonsuz bir döngüye girerse, başka bir lif akamaz, çünkü siz vermezsiniz.

Ayrıca, her ikisinin de karşılaştığı sorunlara yol açan iplikleri ve lifleri karıştırabilirsiniz. Tavsiye edilmez, ancak dikkatlice yapılırsa bazen yapılması doğru olan şey olabilir.


3
Sonsuz bir döngü sadece düzeltilmesi gereken bir hata olduğunu düşünüyorum ve sonsuz bir döngü olduğunda iş parçacıkları sadece oldukça belirsiz bir avantajı var. İlgili buggy olmayan konsept, kullanıcının iptal etmek isteyebileceği uzun süren bir süreç olduğundadır. Bu durumda, iplikler veya lifler kullansanız da, uzun süren işlemin işbirliğine dayalı olması gerekir - iş parçacığının öldürülmesi bazı veri yapılarınızın karışık olmasına neden olabilir, bu nedenle daha iyi bir yol, örneğin uzun süren işlem iş parçacığının periyodik olarak kontrol etmesi eğer kesilmiş olsaydı. Bu, periyodik olarak elde edilen bir elyaftan çok farklı değildir.
Evgeni Sergeev

43

Win32'de, fiber bir tür kullanıcı tarafından yönetilen iş parçacığıdır. Bir fiberin kendi yığını ve kendi talimat işaretçisi vb. Vardır, ancak fiberler OS tarafından programlanmaz: SwitchToFiber'i açıkça çağırmanız gerekir. Bunun aksine, iplikler işletim sistemi tarafından önceden etkili bir şekilde planlanır. Yani kabaca bir lif gerçek bir OS iş parçacığı olmaktan ziyade uygulama / çalışma zamanı düzeyinde yönetilen bir iş parçacığıdır.

Sonuçlar liflerin daha ucuz olması ve uygulamanın çizelgeleme üzerinde daha fazla kontrole sahip olmasıdır. Bu, uygulama çok sayıda eşzamanlı görev oluşturuyorsa ve / veya çalıştırıldıklarında yakından optimize etmek istiyorsa önemli olabilir. Örneğin, bir veritabanı sunucusu iş parçacıkları yerine elyaf kullanmayı tercih edebilir.

(Aynı terim için başka kullanımlar olabilir; belirtildiği gibi bu Win32 tanımıdır.)


37

İlk olarak , süreçler ve iş parçacıkları arasındaki farkın arka plan malzemesi olarak bu açıklamasını okumanızı tavsiye ederim .

Bir kez okuduktan sonra oldukça basittir. İplik kutuları, çekirdeğe, kullanıcı alanına uygulanabilir veya ikisi karıştırılabilir. Lifler temel olarak kullanıcı alanına uygulanan ipliklerdir.

  • Tipik olarak bir iş parçacığı denilen, çekirdeğe uygulanan bir yürütme iş parçacığıdır: çekirdek iş parçacığı olarak bilinen. Bir çekirdek iş parçacığının zamanlaması yalnızca çekirdek tarafından işlenir, ancak bir çekirdek iş parçacığı isterse uyuyarak CPU'yu gönüllü olarak serbest bırakabilir. Bir çekirdek iş parçacığının engelleme G / Ç kullanabilmesi ve çekirdeğin zamanlama konusunda endişelenmesine izin vermesi avantajı vardır. Ana dezavantajı, çekirdeğe sıkışmayı gerektirdiği için iplik değiştirmenin nispeten yavaş olmasıdır.
  • Fiberler, zamanlaması tek bir işlem altında bir veya daha fazla çekirdek iş parçacığı tarafından kullanıcı alanında işlenen kullanıcı alanı iplikleridir. Bu, fiber değişimini çok hızlı hale getirir. Belirli bir paylaşılan veri kümesine erişen tüm fiberleri tek bir çekirdek iş parçacığı bağlamında gruplandırırsanız ve bunların zamanlamasını tek bir çekirdek iş parçacığı tarafından işlerseniz, lifler etkili bir şekilde seri olarak çalışacağından ve tamamladığınızdan senkronizasyon sorunlarını ortadan kaldırabilirsiniz. zamanlama üzerinde kontrol. İlgili lifleri tek bir çekirdek iş parçacığı altında gruplandırmak önemlidir, çünkü içinde çalıştıkları çekirdek iş parçacığı çekirdek tarafından önceden boşaltılabilir. Bu nokta diğer cevapların çoğunda açıklığa kavuşmamıştır. Ayrıca, bir fiberde bloke edici G / Ç kullanırsanız, tüm çekirdek ipliği, bu çekirdek ipliğinin bir parçası olan tüm fiberleri içeren blokların bir parçasıdır.

Modern İşletim Sistemlerinde 11.4 "Windows Vista'da İşlemler ve İş Parçacıkları" bölümünde Tanenbaum şöyle diyor:

Her ne kadar lifler birlikte planlanmış olsa da, lifleri planlayan birden fazla iplik varsa, liflerin birbirini etkilemediğinden emin olmak için çok dikkatli bir senkronizasyon gereklidir. İplikler ve lifler arasındaki etkileşimi basitleştirmek için, yalnızca bunları çalıştırmak için işlemciler olduğu kadar çok sayıda iplik oluşturmak ve her bir çalışmaya iplikleri yalnızca belirli bir işlemci veya hatta tek bir işlemci setinde benzetmek yararlıdır. Daha sonra her bir iplik, liflerin belirli bir alt kümesini çalıştırarak ipliklerle lifler arasında senkronizasyonu kolaylaştıran bire-çok ilişki kurabilir. Yine de liflerle ilgili hala birçok zorluk var. Çoğu Win32 kütüphanesi liflerden tamamen habersizdir ve lifleri iplikmiş gibi kullanmaya çalışan uygulamalar çeşitli arızalarla karşılaşır. Çekirdeğin lifler hakkında bilgisi yoktur ve bir lif çekirdeğe girdiğinde, yürüttüğü iş parçacığı engellenebilir ve çekirdek işlemcide rasgele bir iş parçacığı programlayarak diğer lifleri çalıştırmak için kullanılamaz hale getirir. Bu nedenlerden ötürü, lifler, açıkça liflerin sağladığı işlevselliğe ihtiyaç duyan diğer sistemlerden kod taşınması haricinde nadiren kullanılır.


4
Bu en eksiksiz cevap.
Bernard

12

İplik ve Elyaflara ek olarak, Windows 7'nin Kullanıcı Modu Zamanlaması sunduğunu unutmayın :

Kullanıcı modu zamanlama (UMS), uygulamaların kendi iş parçacıklarını zamanlamak için kullanabileceği hafif bir mekanizmadır. Bir uygulama, sistem zamanlayıcıyı dahil etmeden kullanıcı modunda UMS iş parçacıkları arasında geçiş yapabilir ve bir UMS iş parçacığı çekirdeğe bloke olursa işlemcinin kontrolünü yeniden kazanabilir. UMS iş parçacıkları, her UMS iş parçacığının, tek bir iş parçacığının iş parçacığı bağlamını paylaşmak yerine kendi iş parçacığı içeriğine sahip olması nedeniyle fiberlerden farklıdır. Kullanıcı modunda iş parçacıkları arasında geçiş yapma yeteneği, UMS'yi çok az sistem çağrısı gerektiren çok sayıda kısa süreli iş öğelerini yönetmek için iş parçacığı havuzlarından daha verimli hale getirir.

İplikler, lifler ve UMS hakkında daha fazla bilgi için Dave Probert: Windows 7 İçinde - Kullanıcı Modu Zamanlayıcı (UMS) izlenebilir .


7

Konular OS tarafından planlanır (önleyici). Bir iplik OS tarafından herhangi bir zamanda durdurulabilir veya devam ettirilebilir, ancak lifler az çok kendilerini yönetir (kooperatif) ve birbirlerine verim verir. Yani, programcı elyafların işlemlerini ne zaman yaptığını ve bu işlemenin başka bir elyafa ne zaman geçtiğini kontrol eder.


7

İplikler genellikle ipliği kesmek için çekirdeğe güvenir, böylece başka bir iş parçacığı çalışabilir (bu daha çok Etkili çoklu görev olarak bilinir), oysa lifler, çalışma zamanından vazgeçen fiberin kendisinde kooperatif çoklu görev kullanır, böylece başka lifler de çalışabilir.

Muhtemelen benden daha iyi açıklayan bazı yararlı bağlantılar şunlardır:


7

İplikler başlangıçta hafif süreçler olarak oluşturuldu. Benzer bir şekilde, lifler, kontrol sağlayarak birbirlerini programlamak için liflerin kendilerine (basit bir şekilde) dayanan hafif bir ipliktir.

Sanırım bir sonraki adım, onlara bir talimat (5 yaşındaki oğlumun aksine değil :-) yürütmek istediğinizde onlara bir sinyal göndermek zorunda kalacağınız sanırım. Eski günlerde (ve şimdi bazı gömülü platformlarda bile), tüm iplikler lifti, ön çaba yoktu ve güzel davranmak için ipliklerinizi yazmanız gerekiyordu.


3

Win32 fiber tanımı aslında Sun Microsystems'da kurulan "Green Thread" tanımıdır. Fiber teriminin bir tür iş parçacığında, yani kullanıcı kodu / iş parçacığı kitaplığı kontrolü altında kullanıcı alanında yürütülen bir iş parçacığında harcanmasına gerek yoktur.

Argümanı açıklığa kavuşturmak için aşağıdaki yorumlara bakın:

  • Hiper iş parçacığı ile, çok çekirdekli CPU birden çok iş parçacığını kabul edebilir ve bunları her çekirdeğe bir tane dağıtabilir.
  • Superscalar boru hattılı CPU, yürütme için bir iş parçacığını kabul eder ve iş parçacığını daha hızlı çalıştırmak için Komut Düzeyi Paralelliğini (ILP) kullanır. Bir ipliğin paralel boru hatlarında çalışan paralel liflere bölündüğünü varsayabiliriz.
  • SMT CPU, birden fazla iş parçacığını kabul edebilir ve boru hatlarını daha verimli kullanarak birden fazla boru hattında paralel yürütme için komut liflerine frenleyebilir.

Proseslerin ipliklerden ve ipliklerin liflerden yapılması gerektiğini varsaymalıyız. Bu mantık göz önünde bulundurulduğunda, diğer iplik türleri için lif kullanmak yanlıştır.


Bu ilginç.
JSON
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.