Yanıtlar:
Boost.Asio , ağ üzerinde odaklanarak başlayan bir C ++ kütüphanesidir, ancak eşzamansız I / O özellikleri diğer kaynaklara genişletilmiştir. Ayrıca, Boost.Asio, Boost kitaplıklarının bir parçası olduğundan, diğer Boost kitaplıklarıyla çoğaltmayı önlemek için kapsamı biraz daraltılır. Örneğin, Boost.Asio , Boost.Thread zaten bir iş parçacığı soyutlaması sağlamaz .
Öte yandan libuv , Node.js için platform katmanı olarak tasarlanmış bir C kütüphanesidir . Bu bir Özet sağlar IOCP Windows üzerinde, kqueue MacOS üzerinde ve epoll Linux üzerinde. Ek olarak, kapsamı, iş parçacıkları, iş parçacıkları havuzları ve iş parçacıkları arası iletişim gibi soyutlamaları ve işlevleri içerecek şekilde biraz artmış gibi görünüyor.
Özünde, her kütüphane bir olay döngüsü ve asenkron I / O özellikleri sağlar. Zamanlayıcılar, soketler ve eşzamansız işlemler gibi bazı temel özellikler için örtüşürler. libuv daha geniş bir kapsama sahiptir ve iş parçacığı ve senkronizasyon soyutlamaları, senkron ve asenkron dosya sistemi işlemleri, süreç yönetimi, vb. gibi ek işlevler sağlar. ICMP, SSL, eşzamanlı engelleme ve engellemesiz işlemler gibi özellikler ve bir satırsonu alınana kadar akıştan okuma da dahil olmak üzere yaygın görevler için daha üst düzey işlemler.
İşte bazı önemli özelliklerin kısa yan yana karşılaştırması. Boost.Asio kullanan geliştiriciler genellikle başka Boost kütüphaneleri bulunduğundan, doğrudan sağlandıysa veya uygulanması önemsizse ek Boost kütüphanelerini düşünmeyi seçtim.
libuv Boost Etkinlik Döngüsü: evet Asio Threadpool: evet Asio + Konular Diş: Konular: evet Konular Senkronizasyon: evet Konular Dosya Sistemi İşlemleri: Senkronize: evet FileSystem Asenkron: evet Asio + Dosya Sistemi Zamanlayıcılar: evet Asio Dağılım / Toplama G / Ç [1] : Asio yok ağ: ICMP: hayır Asio DNS Çözünürlüğü: only async asio SSL: hayır Asio TCP: yalnızca asenkron Asio UDP: yalnızca asenkron Asio Sinyal: Kullanım: evet Asio Gönderme: evet hayır IPC: UNIX Alan Adı Yuvaları: evet Asio Windows Adlandırılmış Boru: evet Asio Süreç yönetimi: Ayırma: evet Süreci G / Ç Borusu: evet Süreci Yumurtlama: evet Süreci Sistem Sorguları: CPU: evet hayır Ağ Arayüzü: evet hayır Seri Portlar: hayır evet TTY: evet hayır Paylaşılan Kitaplık Yükleme: evet Eklenti [2]
2. Boost.Eextension asla Boost'a incelenmek üzere gönderilmedi. Belirtildiği gibi burada , yazar bunun tam olarak kabul eder.
Hem libuv hem de Boost.Asio olay döngüleri sağlarken, ikisi arasında bazı ince farklar vardır:
uv_default_loop()
yeni bir döngü ( uv_loop_new()
) oluşturmak yerine varsayılan döngü ( ) kullanılırken dikkatli olunmalıdır .io_service
birden çok iş parçacığının çalışmasına izin veren kendi döngüleridir. Bu Boost'u desteklemek için Asio , bazı performans pahasına dahili kilitleme gerçekleştirir . Asio'nun düzeltme geçmişi , kilidi en aza indirmek için çeşitli performans iyileştirmeleri olduğunu gösterir.uv_queue_work
. İş parçacığı boyutu ortam değişkeni üzerinden yapılandırılabilir UV_THREADPOOL_SIZE
. İş, olay döngüsü dışında ve iş parçacığı içinde yürütülür. İş tamamlandığında, tamamlama işleyicisi olay döngüsü içinde çalışmak üzere sıraya alınır.io_service
bir sonucu olarak kolayca işlev görebilir . Bu, bu örnekte görülebileceği gibi, kullanıcıya iplik yönetimi ve davranış sorumluluğunu koyar .io_service
run
EAGAIN
veya için kontrol etmelidir EWOULDBLOCK
.kill
ile bir soyutlama ve sinyal işleme sağlar.uv_signal_t
uv_signal_*
kill
, ancak signal_set
sinyal işleme sağlar.uv_pipe_t
tür aracılığıyla özetler .local::stream_protocol::socket
ya local::datagram_protocol::socket
ve windows::stream_handle
.API'lar yalnızca dile göre farklı olsa da, burada birkaç önemli fark vardır:
Boost.Asio içinde, bir işlem ile bir işleyici arasında bire bir eşleme vardır. Örneğin, her async_write
işlem bir kez WriteHandler'ı çağırır . Bu, birçok libuv işlemi ve işleyicisi için geçerlidir. Bununla birlikte, libuv'lar çoktan uv_async_send
bire eşlemeyi destekler. Birden fazla uv_async_send
çağrı uv_async_cb'nin bir kez çağrılmasına neden olabilir .
Bir akış / UDP'den okuma, sinyalleri işleme veya zamanlayıcıları bekleme gibi görevlerle uğraşırken Boost.Asio'nun asenkron çağrı zincirleri biraz daha açıktır. Libuv ile belirli bir etkinliğe ilgi göstermek için bir gözlemci oluşturulur. Daha sonra izleyici için bir geri çağrı sağlanan bir döngü başlatılır. Çıkar olayı alındıktan sonra geri arama başlatılacaktır. Öte yandan, Boost.Asio, uygulamanın olayı işlemekle her ilgilenişinde bir işlem yapılmasını gerektirir.
Bu farkı göstermeye yardımcı olmak için, Boost.Asio ile async_receive
çağrının birden çok kez verileceği eşzamansız bir okuma döngüsü :
void start()
{
socket.async_receive( buffer, handle_read ); ----.
} |
.----------------------------------------------'
| .---------------------------------------.
V V |
void handle_read( ... ) |
{ |
std::cout << "got data" << std::endl; |
socket.async_receive( buffer, handle_read ); --'
}
Ve burada, handle_read
gözlemcinin soketin veri içerdiğini her gözlemlediğinde çağrılan libuv ile aynı örnek :
uv_read_start( socket, alloc_buffer, handle_read ); --.
|
.-------------------------------------------------'
|
V
void handle_read( ... )
{
fprintf( stdout, "got data\n" );
}
Boost.Asio'daki asenkron çağrı zincirlerinin ve libuv'daki gözlemcilerin bir sonucu olarak, bellek ayırma genellikle farklı zamanlarda gerçekleşir. Gözlemcilerde libuv, tahsisi hafızanın işlenmesini gerektiren bir olay alana kadar savunur. Tahsis, bir kullanıcı geri çağrısı yoluyla yapılır, libuv için dahili olarak çağrılır ve uygulamanın dağıtma sorumluluğunu ortadan kaldırır. Öte yandan, Boost.Asio operasyonların birçok bellek Böyle durumunda olduğu gibi, uyumsuz işlemi vermeden önce tahsis gerektirir buffer
için async_read
. Boost.Asio, null_buffers
bir olayı dinlemek için kullanılabilecek şekilde sağlayarak uygulamaların bellek gerekene kadar bellek ayırmayı ertelemesine izin verir.
Bu bellek ayırma farkı da bind->listen->accept
döngü içinde kendini gösterir . Libuv ile, uv_listen
bir bağlantı kabul edilmeye hazır olduğunda kullanıcının geri aramasını çağıracak bir olay döngüsü oluşturur. Bu, uygulamanın, bir bağlantı denenene kadar istemcinin tahsisini ertelemesine izin verir. Öte yandan, Boost.Asio listen
sadece durumunu değiştirir acceptor
. async_accept
Bağlantı etkinlik için dinler ve akran gerektirir çağrılan önce tahsis edilecek.
Ne yazık ki, libuv ve Boost.Asio'yu karşılaştırmak için somut bir kıyaslama numaram yok. Ancak, gerçek zamanlı ve gerçek zamanlıya yakın uygulamalarda kütüphaneleri kullanarak benzer bir performans gözlemledim. Eğer sert sayılar isteniyorsa, libuv'un karşılaştırma testi başlangıç noktası olarak kullanılabilir.
Ayrıca, gerçek darboğazları tanımlamak için profil oluşturma yapılırken, bellek ayırmalarına dikkat edin. Libuv için bellek ayırma stratejisi öncelikli olarak ayırıcı geri araması ile sınırlıdır. Öte yandan, Boost.Asio'nun API'sı bir ayırıcı geri aramasına izin vermez ve bunun yerine ayırma stratejisini uygulamaya aktarır. Ancak, Boost.Asio'daki işleyiciler / geri çağrılar kopyalanabilir, ayrılabilir ve yeniden konumlandırılabilir. Boost.Asio, uygulamaların işleyiciler için bir bellek ayırma stratejisi uygulamak amacıyla özel bellek ayırma işlevleri sağlamasına olanak tanır .
Asio'nun gelişimi en az OCT-2004'e dayanıyor ve 20 günlük emsal incelemesinden sonra 22-MAR-2006'da 1.35'e yükseltildi. Ayrıca TR2 için Ağ Kitaplığı Önerisi için başvuru uygulaması ve API işlevi de görüyordu . Boost.Asio'nun yararlılığı kullanıcıdan kullanıcıya değişse de, oldukça fazla miktarda dokümana sahiptir .
API ayrıca oldukça tutarlı bir hisse sahiptir. Ayrıca, zaman uyumsuz işlemler işlemin adında açıktır. Örneğin accept
, eşzamanlı engelleme ve async_accept
eşzamansızdır. API, yaygın bir G / Ç görevi için, örneğin bir akış okunana kadar \r\n
okumak için ücretsiz işlevler sağlar . Ayrıca ip::address_v4::any()
, "tüm arabirimler" adresinin temsil edilmesi gibi ağa özgü bazı ayrıntıların gizlenmesine de dikkat edilmiştir 0.0.0.0
.
Son olarak, Boost 1.47+, hata ayıklama sırasında yararlı olabileceği kanıtlanan işleyici izleme ve C ++ 11 desteğini sağlar.
Github grafiklerine dayanarak, Node.js'nin gelişimi en az FEB-2009'a ve libuv'un geliştirme tarihi MAR-2011'e dayanıyor . Uvbook bir libuv tanıtımı için harika bir yerdir. API belgeleri burada .
Genel olarak, API oldukça tutarlı ve kullanımı kolaydır. Karışıklık kaynağı olabilecek bir anomali, uv_tcp_listen
bir izleyici döngüsü oluşturmasıdır. Bu, gözlemci döngüsünün ömrünü kontrol etmek için genellikle bir uv_*_start
ve bir uv_*_stop
çift fonksiyonu olan diğer gözlemcilerden farklıdır . Ayrıca, bazı uv_fs_*
operasyonların makul miktarda argümanı vardır (7'ye kadar). Senkronize ve senkronize olmayan davranış bir geri çağırma (son argüman) mevcudiyetinde belirlenirken, senkron davranışın görünürlüğü azaltılabilir.
Son olarak, libuv taahhüt tarihine hızlı bir bakış , geliştiricilerin çok aktif olduğunu gösterir.
uv_async_send
çağrı biriktirebilir ve hepsini tek bir geri çağrı ile yönetebilir. Bu belgelenmiştir burada . Ayrıca herkese teşekkürler.
Tamam. Her iki kütüphaneyi kullanma konusunda da deneyimim var ve bazı şeyleri temizleyebilirim.
Birincisi, kavramsal bir bakış açısından, bu kütüphaneler tasarımda oldukça farklıdır. Farklı mimarileri var, çünkü farklı ölçeklerde. Boost.Asio, TCP / UDP / ICMP protokolleri, POSIX, SSL vb. İle kullanılması amaçlanan büyük bir ağ kütüphanesidir. Libuv sadece çapraz platform çekilebilmesi için bir tabakadır IOCP ağırlıklı, node.js için. Bu nedenle libuv işlevsel olarak Boost.Asio'nun bir alt kümesidir (ortak özellikler yalnızca TCP / UDP Soketleri iş parçacığı, zamanlayıcıları). Bu durumda, bu kütüphaneleri sadece birkaç kriter kullanarak karşılaştırabiliriz:
Yeni C ++ özellikleriyle entegrasyon: Asio daha iyidir (Asio 1.51, C ++ 11 asenkron modelini, hareket semantiğini, değişken şablonlarını yaygın olarak kullanır). Olgunluk açısından, Asio iyi belgelere sahip daha istikrarlı ve olgun bir projedir (eğer libuv ile karşılaştırırsanız) üstbilgilerin açıklaması), İnternet'te birçok bilgi (video görüşmeleri, bloglar: http://www.gamedev.net/blog/950/entry-2249317-a-guide-to-getting-started-with-boostasio?pg = 1 , vb.) Ve hatta kitaplar (profesyoneller için değil, yine de: http://en.highscore.de/cpp/boost/index.html ). Libuv'un sadece bir çevrimiçi kitabı var (aynı zamanda iyi) http://nikhilm.github.com/uvbook/index.htmlve birkaç video görüşmesi, bu yüzden tüm sırları bilmek zor olacak (bu kütüphane çok fazla var). İşlevlerle ilgili daha ayrıntılı tartışma için aşağıdaki yorumlarıma bakın.
Sonuç olarak, her şeyin sizin amaçlarınıza, projenize ve ne yapmak istediğinize bağlı olduğunu söylemeliyim.
Büyük bir fark, Asio'nun yazarı (Christopher Kohlhoff) kütüphanesini C ++ Standart Kütüphanesi'ne dahil etmek için hazırlıyor, bkz http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2175 .pdf ve http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4370.html
Taşınabilirlik durumunu ekleme: Bu yanıtı yayınladığım ve kendi girişimlerime göre: