C statik kütüphaneleri kaşlarını çattı mı? [kapalı]


11

Paylaşılan kitaplıklara sahip olmanın 2 argümanı vardır:

  1. Disk alanının azaltılmasına yardımcı olur.
  2. Paylaşılan bir kitaplık güncellendiğinde, ona bağlı olan tüm ikili dosyalar güncelleştirmeyi alır.

Paylaşılan kitaplıklar için temel olarak bir dezavantaj vardır:

  • Bağımlılık cehennemi getirebilirler.

Masaüstü bilgisayarlarda, ilk avantaj artık geçerli değildir. Disk alanını boşa harcamak bu günlerde pek sorun değil.

Statik ikili dosyalara sahip olmak daha iyi paket yöneticileri elde etmemizi sağlayacaktır - yani bağımlılık cehennemi geçmişte kaldı. Bir program eklemek sadece bir ikili dosya eklemek olacaktır; nihayetinde dosyalarını işlemesine izin veren bir klasör. Bir programı silmek, bu dosyayı silmek olacaktır. Bağımlılıklar? Gone.

İkinci avantaj hala duruyor, ancak masaüstü bilgisayarlardaki statik ikili programların avantajından daha ağır basıyor. Yani, Go gibi yeni diller bile, kolaylık nedeniyle paylaşılan kütüphanelerin avantajlarına rağmen tüm ikili dosyalarını derler.


Paylaşılan kütüphanelerin ana avantajlarından biri artık büyük bir şey olmadığından, C statik kütüphaneleri hala kaşlarını çattı mı? Öyleyse neden?


4
C'nin artık kullanılmasının başlıca nedeni, özellikle modern masaüstü bilgisayarlarda çalışmamanızdır .
Telastyn

18
@Telastyn Üzgünüm? Masaüstü bilgisayarlarıma yüklenen yazılımların çoğu C ile yazılmıştır.
Florian Margaine

6
Yan bit - konuyla ilgili bir site dışı okuma - Dinamik Bağlantı Zararlı

6
Dinamik kütüphanelerin bir yararı, insanların kütüphaneleri, güncellemeleri almayı uzun süredir durdurmuş olan 15 yaşındaki kapalı kaynak oyununuzda hatalar, güvenlik açıkları veya donanım sorunları etrafında çalışacak şekilde güncelleyebilmeleridir. Bir tür niş vaka ama iyi oyunlar meta olmadığı için, "sadece başka bir program kullanın" gerçekten yardımcı olmaz. Ayrıca, kendi kodunuzu açık kaynak sağlamadan LGPL ile uyumlu olmak da önemlidir.
Doval

4
Paylaşılan kütüphanelerin diğer iki avantajını da unuttunuz: 1) hafızada da paylaşılıyorlar, 2) tüm bağlayıcılar kötü emiyor ve devasa bir ikili dosyayı bağlamak son derece tatsız. Bir ikiliyi birkaç küçük öğeye bölmek, tüm süreci çok daha tolere edilebilir kılar.
SK-logic

Yanıtlar:


9

Sorunuzun temeli kusurlu. Üzerinde kaşlarını çatmış olan şey, onların arkasındaki temeli anlamadan doktrinerlere ve mutlaklara bağlı kalmaktır (Cargo Cult Programming?).

Bağlantılı SO yanıtı , bu konuda ilginç bir çalışma- Soru, -static seçeneği ile bir derlemenin neden çalışmadığıyla ilgiliydi, bağlandığınız yanıt statik bağlantı kullanmama konusundan başka bir şey değildi. Neden kötü olduğunu tartışmaz ve OP dinamik bağlantı kullanır talep. Onun talihsizliği doğru cevap olarak işaretlenmiştir (aşağıdaki cevap iki kat daha fazla oy içerir ve OP'nin sorusuna doğru cevaptır) çünkü doğru cevap orada olmasına rağmen, dogmatik bir görüş arasında derinden gizlenmiştir.

Asıl soru, statik vs dinamik bağlamanın artıları ve eksileri nelerdir ve ne zaman diğerine tercih edilir.


2
Basile cevabı yok size tam olarak bu yüzden o paylaşılan kütüphaneleri kullanılmasını önerir: ? "Bağlantıya statik başvurunuzu istiyorsun Neden . (Eğer sistem dinamik kütüphaneleri güncellemeleri gelen kar yok çünkü) Bu bir hata genellikle belirli isim servis anahtarı olarak libc'den gelen tesisler dinamik kütüphaneler istiyor. " Sadece katılmamanız nedeniyle" bir rant "değil.
Cody Gray

@Cody Bağlantılı cevap, ben bir rant dediğimden beri düzenlendi. Statik vs dinamik bağlantı üzerine tuttuğum tek fikir, ihtiyaçlarınıza uygun olanı kullanmak ve seçimin güçlü ve zayıf yanlarını anlamaktan ziyade "birisi böyle söyledi" için kargo kült programlama doktrinine düşmektir.
mattnz

Evet, "Özellikle ..." kısmı eklendi. Bunun rant durumunu nasıl etkilediğinden emin değilim. Tabii ki kargo kült programlamasını savunmuyorum. Sadece statik bağlantı savunucuları (tecrübelerime göre) genellikle güvenlik endişelerini özlüyor veya hafife alıyor. Statik bağlantı, bir kereye mahsus yardımcı programlar için çok uygun olabilir, bu da uygulamayı bağımsız hale getirir ve bu nedenle dağıtımı çok daha kolay hale getirir. Ancak, yaygın olarak dağıtılacak veya üretim için kullanılacak herhangi bir uygulama gerçekten paylaşılan bir kütüphaneye bağlanmalıdır. Gerçek bir dezavantaj yoktur: bu uygulama düzeyinde zaten bir dağıtım sürecine ihtiyacınız vardır.
Cody Gray

1
Statik bağlamanın uygun olduğu yere iyi bir örnek, çalıştığım yer - büyük, karmaşık yaşam kritik sistemler. Kritik bir modül çalışma için test edilip onaylandıktan sonra, davranışı 'işlem'den geçmeden değişmemelidir. Ancak, sistemin operasyonel ve hayat dışı kritik parçaları (faturalandırma ve raporlama) daha az sağlam kontrole ihtiyaç duymaz ve dinamik bağlantı kullanmaz.
mattnz

7

Bir geliştirici bakış açısından, dinamik bağlantı genellikle derleme / bağlantı / test döngünüzü önemli ölçüde hızlandırabilir.

Paket yönetimi açısından, örneğin libGL'yi ele alalım. Paket yöneticimde yaklaşık bir düzine farklı uygulama var, bazıları genel ve bazıları da belirli grafik kartlarını hedefliyor. Dinamik olarak bağlı olmasaydı, libGL ile bağlantı kuran her programın bir düzine versiyonunun olması gerekirdi, yoksa bir işlev çağrısı kadar verimli olmayan ek bir soyutlama katmanı tasarlamanız gerekirdi.

Qt gibi popüler bir kütüphanede bir güvenlik sorunu düşünün. Dinamik bağlantı ile, Qt ile bağlantı kuran her paketi tanımlamak, yeniden derlemek ve dağıtmak yerine bu paketi güncelleyebilirim.

Statik bağlamanın bağımsız olarak kurulan kapalı kaynak uygulamalarında avantajları olabilir, ancak açık kaynak paket yönetiminde yardımcı olduğundan daha fazla acıyor.


2
Bu doğrudur (gelişimi hızlandırır), ancak üretimi üretmesi gerçekten sinir bozucu. Standart örnek Firefox'tur. Firefox'un makul bir sürede yüklediği dinamik bağlantı sembolü çözünürlüğünü hızlandıran mühendislik çabası (çirkin hackler şeklinde) miktarı tamamen çılgınca. Tüm proje içi kodlarını statik olarak bağlamak istiyorlarsa, çok daha az mühendislik maliyeti ile çok daha iyi performans elde edilmiş olabilir (yine de istenirse sistem kitaplıklarını ve eklentilerini dinamik olarak bağlar).
R .. GitHub BUZA YARDIMCI DURDUR

5

Paylaşılan kütüphaneler temelde 2. nedenden ötürü Linux dağıtım sahipleri tarafından şiddetle tercih edilir . Örneğin, birisi zlib'de bir güvenlik hatası bulduğunda , zlib kullanan programların her birini yeniden derlemek zorunda olmamaları gerçekten önemlidir - sadece onlara daha fazla CPU döngüsüne mal olmakla kalmaz. yeniden derlerken, dağıtımı kullanan herkesin tüm bu programları yeniden indirmesi gerekir . Bu arada, bir dağıtım tarafından sağlanan paketler kümesinde, bağımlılık cehennemi bir sorun değildir, çünkü her şey bu kütüphane kümesiyle çalışacak şekilde test edilir.

Dağıtımınızda olmayan kütüphanelere ihtiyaç duyan üçüncü taraf yazılımlar oluşturuyorsanız, bu kütüphaneleri statik olarak bağlamak alternatiften daha az güç olabilir ve bu iyi.

Bilmeniz gereken diğer önemli şey, GNU libcve GCC'lerin libstdc++her ikisinin de kütüphane statik olarak bağlıysa güvenilir çalışmayan bileşenlere sahip olmasıdır. En yaygın sorun dlopen, çünkü yüklediğiniz modülün dlopenkendisi dinamik olarak bağlantılıdır libc.so.6. Bu, artık adres alanınızda C kütüphanesinin iki kopyasına sahip olduğunuz anlamına gelir ve iç mallocveri yapısının (örneğin) hangi kopyasının yetkili olduğunu kabul etmediklerinde komiklik sağlanır . Bu da kötüleşiyor: görünmüyor fonksiyonları bir sürü ile ilgisi var dlopengibi gethostbynameve iconv, kullanımdlopendahili olarak (davranışlarının çalışma zamanı tarafından yapılandırılabilmesi için). Neyse ki, libc ve libstdc ++ için ABI çok kararlıdır, bu nedenle dinamik olarak bunları bağlayan sorunlarla karşılaşmanız olası değildir.


2

Mattnz'in son noktasına katılıyorum: bu soru yüklü bir soru. Statik bağlamanın kötü olduğunu varsayar. Bunun neden böyle olmadığının iki sebebini düşünebilirim:

  • Statik bağlantı güvenlidir: paylaşılan bir kitaplık, bir uygulama yenisini kullanacak şekilde güncelleştirilirse (belki yeni, eskisinin üzerine yazılır veya eski kitap kaldırılır), yeni sürümün uygulamayı bozma riski oluşturabilir. Bu, uygulama için resmi bir güncelleme kapsamı dışında yapılan bir kod değişikliğidir. Test edilmemiş olabilir. Statik bağlantı, kütüphaneleri harici olarak paylaşmayarak bunu engeller. Bu risk nedeniyle bu paylaşılan kütüphaneler için bir dezavantaj olduğunu düşünüyorum. Paylaşılan bir kütüphanenin yeni bir sürümü belirli eski uygulamaları bozan yeni bir hata getirirse ne olur?

  • Statik bağlantı bir uygulamanın daha bağımsız olmasını sağlar. Paylaşılan kitaplıklar birincil yürütülebilir dosya ile birlikte konumlandırılabilse de, genellikle paylaşılan konumlarda depolanırlar. Statik bağlantılı uygulamaların "işletim sistemi tarafından sahip olunan dosyalarda, dizinlerde veya ayarlarda değişiklik gerektirmemesi" anlamında "taşınabilir" olmasını sağlamak daha kolaydır (Windows dizini, kayıt defteri, vb.).


Bahsetmek istediğim avantajları geliştirdiğiniz için teşekkür ederiz. Ancak, örneğin Linux dağıtımları tarafından sağlanan paketlerin çoğunu görürseniz, bunlar statik olarak derlenmez. O mu bu statik derleme en azından bakış harici açıdan, hoş karşılanmaz görünüyor.
Florian Margaine

1
Dinamik kütüphaneler bugünlerde hemen hemen tüm işletim sistemlerinde talep üzerine çağrılıyor. Yalnızca gerçekte kullanılan sayfalar bellektir. Birden fazla uygulama aynı işlevselliği kullanıyorsa, belleği paylaşacak ve statik kütüphane durumundan daha azını kullanacaktır. Birden fazla uygulama aynı kitaplıkta farklı işlevler kullanıyorsa, statik yaklaşımla yaklaşık olarak aynı etkiye sahip olacak şekilde her iki işlev kümesi de disk belleği içine alınır.
Alan Shutko

@AlanShutko Bahsettiğin için bu kısmı mücadele ettim ve birkaç şekilde tekrar yazdım. Modern işletim sistemleri pratikte statik yük ile paylaşılan kütüphanelerin verimliliğini sunsa bile, her iki şekilde de gerçek bir garanti yoktur. Tekrar düzenleyeceğim.

@Snowman Bence temel nokta, dinamik bağlantı sağlayan herhangi bir gerçekçi işletim sisteminde (dinamik bağlantı kullanan ancak talep disk belleği kullanmayan herhangi bir işletim sistemi bilmiyorum) ikinci noktanızın su tutmamasıdır: bellek aslında kullanılmaz işlev kullanılmadıkça ve dinamik bir kitaplık tarafından kullanılan bellek, onu kullanan farklı programlar arasında paylaşılabilir ve bu da dinamik sürümün bellek kullanımını daha az değil, daha verimli hale getirir. Birinci ve üçüncü nedenleriniz geçerlidir, ancak ikincisini silerim: herhangi bir gerçekçi varsayımla, bu sadece yanlış.
Jules

@Karşılaşıyorum, modern işletim sistemlerinde sorunlu ve şüpheli geçerliliğe sahip bir nokta. Kaldırdım.

1

Statik ve dinamik kütüphanelerin her birinin kendi kullanımları vardır. Kapsamdaki tek bir uygulamaya baktığımızda, neyin gerekli ve neyin olmadığı hakkında farklı bir fikir ediniriz.

Statik bağlantı, uygulama dağıtımını büyük ölçüde basitleştirir. Farklı sürümleri tespit etmek ve bunlarla uğraşmak zorunda kalmamak. Sadece pişirin ve konuşlandırın.

Dinamik kütüphanelerle bariz avantaj, güncellemeleri bağımsız olarak uygulama yeteneğidir.

Javen ve diğer benzer dinamik bağlantı proje oluşturucularını java için nefret etmemin nedenlerinden biri budur. Belirli bir url'de sonsuza dek ve her zaman tek bir kütüphane sürümünün mevcut olmasını beklerler. Tüm kaynak ve kavanozlar gittiğinden, kimsenin uygulamayı derleyemediği 10 yıl içinde meydana gelen problemi anlamamak.


Bu FooLib1.8kütüphanenin kodunu yürütülebilir paketine standart bir şekilde dahil edebilmek için kullanılmayan programların FooLib1.9, yükseltmek veya düşürmek üzere gönderilen bir yükseltme yardımcı programına izin vermesinin mümkün olmamasının özel bir nedeni var mı ? Klasik Macintosh'ta saklanan yol bu kadar kolay olurdu; bugünün sistemlerinin daha iyi yapamaması için bir neden var mı?
supercat

@supercat belirli bir kütüphanenin her versiyonunun sistemde mevcut olacağını mı söylüyorsunuz? Soruyu anladığımdan emin değilim. OP sorusu daha çok birlikte paketlenecek statik kütüphanelere karşı sistem çapında paylaşılan kütüphanelere yönelikti.
cips

Demek istediğim, çalıştırılabilir bir pakete sahip olması, ihtiyaç duyduğu tüm kütüphaneleri içerdiğinden, içinde bulunan kütüphaneleri yükseltme olasılığını engellememeliydi. Bu nedenle, dağıtımdan sonra bir şeyleri yükseltme yeteneğini, bir uygulamayı kütüphaneleriyle bir araya getirmemenin bir avantajı olarak göreceğimi bilmiyorum.
supercat

Belirli bir kütüphanenin lisansı, paketinizle birlikte dağıtılmasına izin veriyorsa, bunu yapmak için her zaman tercih edilen yoldur. Dış bağımlılıkların sayısını azaltır. Her şeyi dağıtacağınızdan, bir yükseltme veya yama mekaniği statik veya dinamik ile aynı şekilde çalışır. Yamalama genellikle ikili deltalara dayanır. Fark olmazdı.
cips
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.