Forum: D Programlama Dili RSS
event,epoll,kqueue bunlar tam olarak nedir.
darkofpain #1
Üye Ağu 2013 tarihinden beri · 58 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Konu adı: event,epoll,kqueue bunlar tam olarak nedir.
Merhaba arkadaşlar,

Socket programlama,non-blocking yapı ve performans derken hata burada bu konuda örnekler geçti yazışmalar oldu ali hoca nın örneklerini kurcalarken filan araştırmaları sonucu aslında yanlış yolda olduğumu fark ettim.

Geçenler socket programlama konusunu non-blocking yapı olaylarını python ile ele aldım tornado,gunicorn gibi sistemleri inceledim onları incelerken event,epoll,kqueue bunlarla karşılaştım.

Bunların ne olduğunu tam olarak anlayamadım ama yapılan bir çok örnekte belli kısımlarda thread ile ama çoğunlukla event,epoll,kqueue ile işlemleri yapıyorlar tabiki epoll(unix,linux) kqueue(mac,bsd) için bunlar tam olarak nedir ne iş yaparlar.

Ayrıca burada ali hocanın yaptığı örnekte her gelen bağlantı için bir işçi başlatması ve işlemleri onun üzerinden yapması gibi örneklemeler yaptık ancak bu yöntem tam olarak doğru yöntem değil

D ile bunlar nasıl kullanılıyor ve tam olarak işlevleri nelerdir bu konuda cevaplarınızı fikirlerinizi arkadaşlar.

Yapmak istediğim olayın genel adı "Asynchronous Networking / Non-Blocking I/O"

Vibe.d nin performansı hakkında şurada bir yazısı var. http://vibed.org/features (Performans başlığı altında)

Bazı bulduğum örnekler,
https://github.com/jarlah/d2-simple-socket-server
https://github.com/D-Programming-Deimos/libevent
https://github.com/D-Programming-Deimos/libevent
https://github.com/adilbaig/Epoll-D2
http://www.google-melange.com/gsoc/proposal/review/google/…
Bu mesaj darkofpain tarafından değiştirildi; zaman: 2013-10-03, 02:46.
acehreli (Moderatör) #2
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Ben bildiğim kadarını yazacağım ama en doğrusunun bu gibi sistem konularını ve kütüphanelerini kendi kaynaklarından okumak olduğunu düşünüyorum.

Örneğin, çalıştığım yerde biz libevent kullanıyoruz ama o kütüphanenin yeteneklerinden yalnızca bizim işimize yarayan kadarını kullanıyoruz.

darkofpain:
event,epoll,kqueue bunlarla karşılaştım.

libevent, sistemde gerçekleşen ve programı ilgilendiren olayları olay (event) olarak sunar:

  • Sinyaller. Örneğin, program bir alt program başlatmıştır; o program sonlandığında başlatana SIGCHLD sinyali gelir; libevent o sinyali bir "şu sinyal oluştu" olayı olarak gösterir.

  • Zamanlayıcılar (timer). Örneğin, program her bilmem kaç saniyede bir işlem yapmak ister; onun için bir zamanlayıcı başlatır ve libevent onu "şunun zamanı geldi" olayı olarak gösterir.

  • Dosya okuma ve yazma. Örneğin, program uzun bir yazma işlemi başlatır ve libevent "şu yazma bitti" olayı olarak gösterir.

  • vs.

İşin güzeli, doğal olarak eş zamanlı gerçekleşen bu tür olaylar programda tek iş parçacığı tarafından halledilebilir. Bu, programda olay döngüsü (event loop) denen döngüde programın "sıradaki olay nedir" diye sorması ve her seferinde libevent'in sunduğu tek olaya yanıt vermesi ile sağlanır.

Benim çalıştığım yerde libevent aynı bu biçimde kullanılıyor: Programımız tek iş parçacığı üzerinde çalışıyor ama her olay kendi başına gelişirken aynı anda birden çok iş yapılmış oluyor.

Yan bilgi olarak, programımızın tek iş parçacığı üzerinde çalışıyor olmasının tek nedeni, alt düzey kütüphanemizin C dilinde yazılmış olması ve eş zamanlı programlamanın C'de hataya açık olması. On sene önce bu tasarımı yapan programcılar çok doğru bir karar vermişler ve bu sayede bu program on senedir ayakta kalabilmiş. libevent yerine C'de veri paylaşımına dayanan eş zamanlı programlama kullansalar işin içinden çıkılamazdı.

Ayrıca burada ali hocanın yaptığı örnekte her gelen bağlantı için bir işçi başlatması ve işlemleri onun üzerinden yapması gibi örneklemeler yaptık ancak bu yöntem tam olarak doğru yöntem değil

Mühendislik açısından bakınca her yöntem durumuna göre en doğru yöntem olabilir. Ama evet, iş parçacıklarının genel sorunları iş parçacığı kullanan her programda ortadadır.

D ile bunlar nasıl kullanılıyor

O konuda libevent ilintilerinin var olduğun dışında bir bilgim yok:

  https://github.com/D-Programming-Deimos/libevent

Yapmak istediğim olayın genel adı "Asynchronous Networking / Non-Blocking I/O"

Genel adı o ama özel bir uygulamasını arıyorsun çünkü o çok genel kavramların buradaki örneklerinin işine yaramadığını biliyoruz.

Vibe.d nin performansı hakkında şurada bir yazısı var. http://vibed.org/features (Performans başlığı altında)

Hızlıca göz gezdirince Vibe.d'nin fiber'ları (başka adıyla co-routine) nasıl etkin olarak kullandığından bahsediliyor. Fiber, eş zamanlı işleri farklı iş parçacıklarına yaptırmak yerine aynı iş parçacığının farklı işleri parça parça ilerletmesi temeline dayanır.

Python'daki 'yield' anahtar sözcüğü ile o dilin temel bir olanağıdır. Go dilinde de "goroutine" diye geçer. D'de dilin temel olanağı olmadığı için kütüphane olanakları olarak çözülür. Bu konuda da deneyimim yok ama en azından Phobos'ta core.thread.Fiber olduğunu biliyorum:

  http://dlang.org/phobos/core_thread.html#.Fiber

Ali
darkofpain #3
Üye Ağu 2013 tarihinden beri · 58 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
off kafam karma karışık hal aldı :D

peki nasıl bir yöntem izleyipde port üzerinden gelen istekleri kabul edip işleyip cliente cevap vermeliyim ve ileride tıkanmasın çökmesin performanslı olması için

herşeyi kavradım çözdüm cookie sinden file uploadına vss.. ancak şu performans için gerekli olaylarlarda tıkandım acıkcası

ayrıca bu libevent olayına girmeden bunu nasıl çözebilirim python ile yapılan tornado tamamen epoll,kqueue ile yapılmıştır

epoll,kqueue d ile karşlığı nedir desteği varmıdır.

Tornado Threading ve concurrency hakkında yazısı
https://github.com/facebook/tornado/wiki/Threading-and-con…
Bu mesaj 2 defa değişti; son değiştiren: darkofpain; zaman: 2013-10-03, 07:49.
acehreli (Moderatör) #4
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
darkofpain:
nasıl bir yöntem izleyipde port üzerinden gelen istekleri kabul edip işleyip cliente cevap vermeliyim ve ileride tıkanmasın çökmesin performanslı olması için

Belki de birden fazla yöntem aynı derecede kullanışlıdır. Belki de yavaşlık sunucuda değil de disk erişiminde, ağ bağlantısında, veya başka bir yerdedir. Kimbilir. Belki de bu projeyi farklı yollarla yapıp yararlarını ve zararlarını göreceksindir...

epoll,kqueue d ile karşlığı nedir desteği varmıdır.

Ben o gibi bilgiler için Google'da "epoll d programming language" diye aratıyorum. Genelde sonuçlar tatmin edici oluyor.

Ali
darkofpain #5
Üye Ağu 2013 tarihinden beri · 58 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
araştırmalarım sonucu fark ettim ki tango kütüphanesinde bu konuda socket,epoll,kqueue socket stream non-blocking i/o konusunda daha güçlü
acehreli (Moderatör) #6
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Teşekkürler. O zaman bu gibi konularda Tango'yu kullanmak daha akıllıca.

Ali
darkofpain #7
Üye Ağu 2013 tarihinden beri · 58 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Asıl ben teşekkür ederim.

Tango kütüphanesinde asyncronous i/o, socket server mevcut

Non-blocking için ufak bir örnek http://www.dsource.org/projects/tango/ticket/1651
Asyncronous I/O için bir açıklama http://www.dsource.org/projects/tango/ticket/2040

ayrıca şöyle bir yazı ile karşılaştım belki ilgi çeker http://dotnot.org/blog/index.php

sanırım tango bir kaç şey değil bir çok konuda phobos dan daha güçlü

Yaptığım ufak test sonucunda

Tango socket örneği stress testinde toplam 400 bağlantı kabul edebildi sonra çöktü
import tango.io.Stdout;
import tango.net.Socket;
import tango.net.ServerSocket;
import tango.net.SocketConduit;
 
int main() {
     Socket server = new Socket(AddressFamily.UNIX,
                                SocketType.STREAM,
                                ProtocolType.IP);
 
     while(true){
         Socket client = server.accept();
 
         char[1024] buffer;
         client.receive(buffer);
 
         Stdout.format("The client said'{}'.", buffer);
 
         client.shutdown(SocketShutdown.BOTH);
         client.detach();
     }
     return 0;
}

Phobos socket örneği stress testinde toplam 150 bağlantı kabul edebildi sonra çöktü
import std.stdio;
import std.socket;
 
void main() {
    Socket server = new TcpSocket();
    server.setOption(SocketOptionLevel.SOCKET, SocketOption.REUSEADDR, 
true);
    server.bind(new InternetAddress(8080));
    server.listen(1);
 
    while(true) {
        Socket client = server.accept();
 
        char[1024] buffer;
        auto received = client.receive(buffer);
 
        writefln("The client said:\n%s", buffer[0.. received]);
 
        enum header =
            "HTTP/1.0 200 OK\nContent-Type: text/html; charset=utf-8\n\n";
 
        string response = header ~ "Hello World!\n";
        client.send(response);
 
        client.shutdown(SocketShutdown.BOTH);
        client.close();
    }
}
darkofpain #8
Üye Ağu 2013 tarihinden beri · 58 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
ali hocam şöyle birşey düşündüm.

şimdi diyelim server üzerine 400 kullanıcı geldi anlık talhanın bana dediği gibi gelen bağlantıları bir diziye toplasak wrk isimli http benchmark programında şöyle bir yapı var -c 400 dediğinde 400 kullanıcı oluşturuyor ve enter dediğimiz zaman

400 user 12 thread yazıyor yani 400 kullanıcının veri alışverişini yapmak için 12 tane thread üzerinde paylaşıyor bizde gelen 400 veya 500 veya 1000 isteği diziye alıp sonra kaç bağlantı olduğuna bakaraktan ufak bir matematiksel hesap bile mesala 500 istek geldi ise bunları işelemesi için 15 thread başlatıp paylaştırsak nasıl olur sizce ve nasıl yapabilirim ?

yanlız tek port yerine 5 portı dinliyor olacağım ancak 5 port için child process başlatıp her bir childe bir portu dinlettiricem böylelik 400x5 olacak.

veya ufak bir önbellekleme yaptığımda harika bir hız elde edebilirim diye düşünüyorum önbellek olarak kastım her gelen sayfanın adresine get adresine göre önbelleğe atıyacağım aynı adrese tekrar giren olur ve değişiklik yoksa direk önbellekten okurum

sonuçta facebook gibi bir kullanıcı kitlesi olmayacak farz edelim olsa bile böylelik sunucular coğalacak ve yatay olarak ölçeklenecek hal böyle olunca sonuçta binlerce veya milyonlarca isteği kabul edebilicek rahatlıklada cevaplayabilicektir.
acehreli (Moderatör) #9
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Çok mantıklı. İstekler bir kuyruğa yerleştiriliyorlar. Yanıtları oluşturacak olan 15 iş parçacığı bu kuyruktan istek çekip çalışmaya başlıyor. İşi bittiğinde yanıtını gönderiyor ve varsa yeni bir istek çekiyor.

Ali
darkofpain #10
Üye Ağu 2013 tarihinden beri · 58 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
ama sabit iş parçacığı 15 adet ile sınırlandırmak yerine gelen istekle paralel olarak mesala 100 istek için 10 tane yetebilir ama 500 istek içinde 20 tane başlatılır.

peki bunu hesaplamak ve istekleri diziye alma işlemini nasıl yapabilirim yardımcı olabilirmisiniz.
acehreli (Moderatör) #11
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
darkofpain:
ama sabit iş parçacığı 15 adet ile sınırlandırmak yerine

Eğer iş parçacığı adedini beklemekte olan istek adedinin bir fonksiyonu olarak tanımlayabiliyorsan kaba hatlarıyla basit bir işlem gibi görünüyor:
size_t gerekenİşçi(size_t bekleyenİstek)
{
    // Senin programınca nasıl bir algoritma olacağını buradan
    // bilemeyiz. Herhalde denemeler yaparak bileceksin. Rasgele bir
    // algoritma:
    return (bekleyenİstek / 10) + 1;
}
 
void main()
{
    // Burada isteği kuyruğa yerleştir
 
    // Burada bu hesapları yap
    size_t beklemekteOlanİstekAdedi = 1000;
    size_t mevcutİşçiAdedi = 3;
 
    if (gerekenİşçi(beklemekteOlanİstekAdedi) < mevcutİşçiAdedi) {
        // Burada yeni işçi başlat
    }
 
    // Burada boş bir işçiye bekleyen bir isteği ver
}
peki bunu hesaplamak ve istekleri diziye alma işlemini nasıl yapabilirim yardımcı olabilirmisiniz.

Hesaplama yukarıdaki gibi basitçe olabilir.

Diziye alma sorusu diğerinden daha da basit olduğu için ya ben bu soruların karmaşıklığını anlamıyorum ya da sen gereğinden daha karmaşık olduklarını sanıyorsun. :) D'de diziye eleman almaktan kolay ne var? :)
struct İstek
{
    // ...
}
// ...
    İstek[] istekler;
    // ...
    istekler ~= yeniİstek;
Ali
darkofpain #12
Üye Ağu 2013 tarihinden beri · 58 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
teşekkür ederim.

öğrendiğim bazı bilgiler neticesinde http işlemlerinde threadlar çok tavsiye edilmez eş zamanlılık (concurrency) tavsiye ediliyor.

google ın dili olan Golang de herşey concurrency üzerine kuruludur o yüzden temiz bir mantık ile tamamen eş zamanlama üzerine yönelmek daha mantıklı ancak thread lar gelen istek icerisinde yapılacak işlemler için kullanılabilir mesala template sınıfı varsa burada parse yaparken kullanılabilir gibi.

Go lang de dahili http sunucu çok büyük projeler üzerinde kullanılabilir bir yapısı var ve tamamen concurrency üzerine kurulur.

burada önemli olan i/o hızlı bir şekilde okuyup çıktı vermesi gerekiyor ve engelleme yapmadan.

http://vimeo.com/49718712 = Rob Pike - 'Concurrency Is Not Parallelism'
acehreli (Moderatör) #13
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
darkofpain:
http işlemlerinde threadlar çok tavsiye edilmez eş zamanlılık (concurrency) tavsiye ediliyor.

Orada bir terim karmaşası var çünkü eş zamanlılık çoğu zaman thread'ler ile sağlanır. Örneğin Phobos'un std.concurrency (ve std.parallelism) modülü perde arkasında thread kullanır.

Golang de herşey concurrency üzerine kuruludur o yüzden temiz bir mantık ile tamamen eş zamanlama üzerine yönelmek daha mantıklı

Eş zamanlılığın Go'nun da kullandığı daha hızlı bir gerçekleştirmesi daha var: Go'nun goroutine, başkalarının coroutine, fiber, greenlet, vs. diye adlandırdıkları kavram.

Daha önce burada geçmiş miydi? Martin Fowler disruptor denen bir mimariyi anlatıyor:

  http://martinfowler.com/articles/lmax.html

CPU'nun iş parçacıkları üzerinde sürekli gezinmelerinin getirdiği masraftan kurtulmak için onları yalnızca giriş ve çıkış noktalarında kullanıyorlar. Asıl işi ise tek iş parçacığı hallediyor.

http://vimeo.com/49718712 = Rob Pike - 'Concurrency Is Not Parallelism'

Şu anda o filmi izleyemiyorum ama en azından başlık konusunda içim rahat. :) Parallelism (koşut işlemler) ve concurrency (eş zamanlı programlama) kavramlarının farklı olduklarını kitabın ilgili bölümlerinde önemle belirtiyorum.

Ali
Doğrulama Kodu: VeriCode Lütfen resimde gördüğünüz doğrulama kodunu girin:
İfadeler: :-) ;-) :-D :-p :blush: :cool: :rolleyes: :huh: :-/ <_< :-( :'( :#: :scared: 8-( :nuts: :-O
Özel Karakterler:
Bağlı değilsiniz. · Şifremi unuttum · ÜYELİK
This board is powered by the Unclassified NewsBoard software, 20100516-dev, © 2003-10 by Yves Goergen
Şu an: 2017-11-18, 00:24:08 (UTC -08:00)