Forum: Ders Arası RSS
Gelin D tadında bir pizza yapalım...:)
pizza Dlang (kuruluş 2012)
Sayfa:  önceki  1  2 
Avatar
Salih Dinçer #16
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Yanıtlanan mesaj ID 5521
Merhaba,

Maalesef ayrı bir sınıf içindeki işlevler ile spawn()'ı anlaştıramadım. Delagate bilmem ne hatası veriyor. Ancak başka bir şey denedim ve isimsiz işlevleri Thread yapıp yapamayacağımızı araştırmak aklıma geldi ama şimdi değil! Habercilerin dediği gibi azzzz sonra...:)

Zafer Çelenk:
Salih Dinçer:
Hatta fırın da yanmayabilir ki önemli olan başta, ortada ve belki sonda karışık bir şekilde (rasgele değil ranfomize fonksiyonundan şimdilik uzak durmalı) herhangi bir işlevin Thread özelliğiyle çağrılması bize bu yapının inceliklerini daha iyi anlamamızı sağlayabilir. Ama spawn() yoluyla, yani dolaylı bir şekilde Thread'ların oluşturulması beni rahatsız ediyor.
Salih anladığım kadarıyla senin esas denemek istediğin kanal (thread) mekanizması o sebeple fırınla, kilerle yada diğer nesnelerle çok zaman harcamak istemiyorsun
Aynen öyle ve basit oldu ama şöyle bir kod yazdım:
/*
    spawnTest.d (10.04.2012)
*/
import core.thread, std.concurrency, std.random;
import std.stdio: writeln;
import std.string: format;
 
    void birinci (Tid anaKimlik, shared(Say)* xSay)
    {
        receive ((int xBekle)
        {
            send(anaKimlik, format("Ben (1.) birinciyim ve ",
                                   "%d saniye beklemeliyim!", xBekle));
            //Thread.sleep(dur!"seconds"(xBekle));
        });
        scope(exit)
        {
            writeln("- birinciydim: ", ++xSay.birinciyi);
            send(anaKimlik, 1);
        }
    }
 
    void ikinci (Tid anaKimlik, shared(Say)* xSay)
    {
        receive ((int xBekle)
        {
            send(anaKimlik, format("Ben (2.) ikinciyim ve ",
                                   "%d saniye beklemeliyim!", xBekle));
            Thread.sleep(dur!"seconds"(xBekle));
        });
        scope (exit)
        {
            writeln("- ikinciydim: ", ++xSay.ikinciyi);
            send(anaKimlik, 2);
        }
    }
 
    shared struct Say { int birinciyi, ikinciyi; }
 
void main() {
    shared auto say_da_Bakam = Say(); // sayıyorrrr bakam...:)
 
    auto birinciTid = spawn(&birinci, thisTid, &say_da_Bakam);
    auto ikinciTid = spawn(&ikinci, thisTid, &say_da_Bakam);
   
    bool flipFlop = true;
   
    int[] rakamlar = [ 2, 4, 8];
    auto rasgeleOlsun = Random(unpredictableSeed);
 
    while (true)
    {
        foreach (rasgele; randomCover(rakamlar, rasgeleOlsun))
        {
            if(flipFlop)
            {
                send(birinciTid, rasgele);
                receive ((string xDurum)
                {
                    writeln(xDurum);
                });
 
                flipFlop = false;
            } else {
                flipFlop = true;
 
                send(ikinciTid, rasgele);
                receive ((string xDurum)
                {
                    writeln(xDurum);
                });
            }
            final switch (receiveOnly!int())
            {
                case 1: birinciTid = spawn(&birinci, thisTid, &say_da_Bakam);
                break;
                case 2: ikinciTid = spawn(&ikinci, thisTid, &say_da_Bakam);
            }
        }
    }
}
Şöyle çalışıyor ama ben yine çok bir şey anlamadım! Bir şeyler ters gidiyor gibi ama anlayamadım işte...:)

Çıktısı:
[salih@telyeweb ders]$ d.sh spawnTest.d
- birinciydim: 1
Ben (1.) birinciyim ve 2 saniye beklemeliyim!
Ben (2.) ikinciyim ve 4 saniye beklemeliyim!
- ikinciydim: 1
- birinciydim: 2
Ben (1.) birinciyim ve 8 saniye beklemeliyim!
Ben (2.) ikinciyim ve 2 saniye beklemeliyim!
- ikinciydim: 2
- birinciydim: 3
Ben (1.) birinciyim ve 4 saniye beklemeliyim!
Ben (2.) ikinciyim ve 8 saniye beklemeliyim!
: : :

^----------- Kuramsal olarak böyle sonsuza kadar gidiyor...
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
acehreli (Moderatör) #17
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ı
zafer:
invariant'ın ne işe yaradığı konusunda kafam karıştı

Nesnenin tutarlılığını denetler. Örneğin her defasında hesaplamayalım diye dikdörtgenin alanını hazırda bulunduruyoruzdur. Bir kenarının uzunluğu değiştiğinde bu hazırdaki alanı da değiştirmemiz gerekir.

Bu tabii basit bir örnek. Genel olarak nesnenin tutarlı veya kullanılabilir olabilmesi bazı şartlara bağlıdır. invariant blokları onları denetler:

    invariant() {
        assert(alan == genişlik * uzunluk);
}

Peki ne kazandık? Çünkü o hesap için de süre harcıyoruz: Hız kazancı için hazırda bulundurduğumuz 'alan' üyesini ilgili olsun olmasın her işlemden sonra invariant bloğu içinde tekrar tekrar genişlik*uzunluk hesabı ile karşılaştırıyoruz.

İşte -release durumunda koddan çıkartılmalarının nedenlerinden birisi budur. Kod denenmiş ve doğru çalıştığına güvenilmişse artık o denetimlere gerek yoktur.

çünkü zaten üretimi tamamlanan programları bizler her zaman -release modu
nda derlemez miyiz?

Evet ve bazen hayır. :)

Evet, teoride öyle ama eğer programın bütün kullanıcı testleri -release olmayan modda uygulanmışsa, testler geçti diye bir de -release modunda derleyiverip son kullanıcıya öyle verebilir miyiz? Ne yazık ki hayır.

Bazı programların hataları ancak -release modunda ortaya çıkar. Bunların nedenleri arasında derleyicinin kendi eniyileştirme hataları olabileceği gibi programcının tanımsız davranışlarının etkileri de olabilir.

Yani evet, programlar -release modunda kullanıma sunulurlar ama ben öyle olmayan firmalarda da çalıştım. Programlar debug modunda ne kadar denenmiş olursa olsun release modunda patlıyordu. Firmalar da gayet güzel debug modunda derlenmiş programı çıkartıyorlardı. Yapacak bir şey yok. :)

Bu olanaklar sadece programcı için hazırlarmış anlamına mı geliyor?

Evet. Zaten C ve C++'ta da assert() bir makrodur ve NDEBUG makrosu tanımlandığında bütün assert()'ler boş hale gelirler.

Ama D bu konuda ek bir yardım getiriyor: Bazen "buraya hiçbir zaman gelinmemelidir" anlamında yazılan assert(false) (ve tabii assert(0), vs.) çağrıları ise koddan çıkartılmazlar. Yani mantıksal ifadesi false veya 0 hazır değerini içeriyorsa o assert()'ler özeldirler ve -release modunda bile kodda dururlar.

assert() ve enforce() arasındaki yakınlık sözleşmeli programlamanın 'in' blokları konusunda bir güçlük getirir: Parametrelerle ilgili denetimleri 'in' bloklarına assert() olarak mı yazalım yoksa işlevin hemen başına mı yazalım?

Yani şu mu?

int kareKök(int sayı)
in {
    assert(sayı >= 0, "Sayı sıfırdan küçük olamaz");
}
body
{
    // ...
}

Yoksa şu mu?

int kareKök(int sayı)
{
    if (sayı < 0) {
        throw new Exception("Sayı sıfırdan küçük olamaz");
    }
 
    // ...
}

Ve tabii aslında enforce() ikincinin yazımını kolaylaştırıyor:

import std.exception;
 
int kareKök(int sayı)
{
    enforce (sayı >= 0, "Sayı sıfırdan küçük olamaz");
 
    // ...
}

Yanıt şöyle: Eğer kareKök() yalnızca programın kendi kodları tarafından çağrılıyorsa yani bu modülün kullanıcılarına açık değilse, o zaman denetim 'in' bloğuna yazılmalı. Böylece program bir kere denendikten sonra -release modunda denetimler de ortadan kalkarlar ve gereksizce genişlik*uzunluk gibi hesaplarla zaman harcamazlar.

Ama eğer bu modülün arayüzünde bulunan bir işlevse, o zaman programı biz ne kadar denemiş olursak olalım kullanıcıların yanlış parametre göndermeyeceklerinden emin olamayız. O yüzden arayüz işlevlerinin giriş koşullarını her zaman için işlevin içinde denetlememiz gerekir.

Ve bu denetimler assert() de olamazlar çünkü yanlış sonuçlar üretmek de istemediğimiz için denetimlerin ortadan kalkmalarını da istemiyoruz.

Diğer notlar:

1) Nitelik işlevleri sanki türlerin bir üyesine erişiyormuş gibi düşünülürler. Sanki nesnenin 'uzunluk', 'renk', 'ağırlık', vs. gibi bir niteliğine eriştirirler. O yüzden bu işlevlerin isimleri 'isim halinde' seçilir. Ve o yüzden bence VerFirinSicakligi yerine kısaca 'sicaklik' olmalı.

2) Benzer şekilde, IsBitisSuresi'nin de isminde eylem görülmediği için sanki bir nitelikmiş gibi algılanabiliyor. Aslında "10 saniye bekle" gibi bir açıklamaya gerek duyulmuş olması da o konuda bir gariplik olduğunu gösteriyor.

3) Şu anda Eş Zamanlı Programlama bölümünü İngilizceleştiriyorum ve doğal olarak kodları da gözden geçiriyorum ve yeniliyorum. Oradaki örneklerde ben de 'saniye' gibi süreleri int olarak tanımlamışım. O kodları int yerine Duration kullanacak şekilde değiştiriyorum.

Bu, bu koddaki IsBitisSuresi()'nin parametresinin de int olmasından aklıma geldi. Parametrenin ismini 'saniye' seçerek sürenin biriminin saniye olduğunu belirtiyoruz ama bu bile kırılgan oluyor çünkü ilerideki bir zamanda birim milisaniye'ye dönüşse parametrenin ismi saniye olarak unutulmuş olabilir.

İşte bu nedenlerle süre olarak Duration çok uygun. Çağıranlar isterlerse saniye gönderirler isterlerse başka bir birim:

import std.stdio;
import core.thread;
 
void bekle(Duration süre)
{
    writeln("Beklemeye başladım");
    Thread.sleep(süre);
    writeln("Bekledim");
}
 
void main()
{
    Duration birSüre = dur!"msecs"(500);
    bekle(birSüre);
 
    bekle(dur!"seconds"(1));
}

Ali
Avatar
Salih Dinçer #18
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Hocam şu pizza Dlang'a da bir el atsan nasıl olur?

Hatta baştan yazabiliriz çünkü başkasının kodu üzerinden zor oluyordur. Çalışırsa (şirket kara geçerse) söz pizza ısmarlayacağım...:)
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
acehreli (Moderatör) #19
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ı
Salih Dinçer:
Hocam şu pizza Dlang'a da bir el atsan nasıl olur?

Bugün çok nöron kaybettim galiba! :p pizza Dlang nedir? Bu konuda konuştuğumuz program değil mi?

Ali
Avatar
Salih Dinçer #20
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Sanırım pizza ısmarlarsam nöronlar artacaktır...:)

Hangi markayı seversin ve adresini özelden yollar mısın? Benim tercihim Little Caesars ama seçim senin. Bu arada pizza Dlang bizim bu ay kurduğumuz yeni bir şirket. Hatırladın değil mi? Kuruluş 2012...:)
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
zafer #21
Üye Tem 2009 tarihinden beri · 700 mesaj · Konum: Ankara
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Yanıtlanan mesaj #17
acehreli:
1) Nitelik işlevleri sanki türlerin bir üyesine erişiyormuş gibi düşünülürler. Sanki nesnenin 'uzunluk', 'renk', 'ağırlık', vs. gibi bir niteliğine eriştirirler. O yüzden bu işlevlerin isimleri 'isim halinde' seçilir. Ve o yüzden bence VerFirinSicakligi yerine kısaca 'sicaklik' olmalı.

Nitelikler hakkında aynen senin gibi düşünüyorum ama sanırım C#'dilinden gelen bir alışkanlık get-set metodlarını kullanmak bence daha güzel bir kodlama oluşturuyor. Tabi ben get-set yerine ver-yap ikilisini tercih ediyorum :) Bu sebeple bir üye değişkeni değiştiren @property metotlarını isimlendirirken eğer üyeyi değiştiriyorsa yap (set), yok eğer üyenin değerini kullanıcıya sunuyorsa ver (get) ön ekini eklemek bana iyi bir yöntemmiş gibi geliyor.


2) Benzer şekilde, IsBitisSuresi'nin de isminde eylem görülmediği için sanki bir nitelikmiş gibi algılanabiliyor. Aslında "10 saniye bekle" gibi bir açıklamaya gerek duyulmuş olması da o konuda bir gariplik olduğunu gösteriyor.

O açıklamayı yazarken senin bu yorumu yapacağın aklıma geldi yinede yazdım :) Yazdım çünkü daha öncesinde hakkında bir konuşma yapmadığımız bir kodu insanların önüne koyarken en azından nasıl düşündüğümü anlamaları için bir takım sınırlamalar getirerek kodların daha anlaşır olmasını istedim. Yoksa "10 saniye bekle" açıklaması tamamen gereksiz neticede zaten metotun parametresi 10 değerini net bir şekilde açıklıyor.

Diğer taraftan IsBitisSuresi metotdunun nitelikmiş gibi algılanması bir sıkıntı ancak ben o metodu private ile işaretleyerek zaten koruma altına aldım. Dolayısıyla nitelik veya başka şekilde düşünen düşünsün sorun değil ona sınıfı düzenleyen kişiden başka kimse erişemez. Ancak isimlendirme açısından haklısın, daha iyi bir isim verilebilirdi. Sanırım IsBitisSuresiKadarBekle() daha iyi olur, sen ne dersin Ali?

Parametrenin ismini 'saniye' seçerek sürenin biriminin saniye olduğunu belirtiyoruz ama bu bile kırılgan oluyor çünkü ilerideki bir zamanda birim milisaniye'ye dönüşse parametrenin ismi saniye olarak unutulmuş olabilir.

Buradaki saniye çalışma süresini simüle etmek için kullanılıyor. Dolayısıyla sınıf dışından bir müdahale yok, tamamen sınıfın kendi işleyi ile ilgili bir durum, bu sebeple ben int saniye isimlendirmesini bu yapı için çok anormal görmüyorum. Malum her olayı içinde bulunduğu ortamda değerlendirmek gerekir.

Ancak seninde belirttiğin gibi hem daha güzel bir programlama örneği olması açısından hemde daha esnek ve genişletilebilir bir yapı sağladığı için Duration kullanımıda gayet güzel olur.

Firin sınıfın son durumunu paylaşmak istiyorum, eleştiri ve önerileri bekliyorum;

/**
* Firin.d
*
* Firin sinifi tarihçesi
*   + VerGazMiktari() metodu eklendi.
*   + YazGazMiktari() metodu eklendi.
*   * Fırının yakılması sırasında harcanmayan gaz miktarı hatası düzeltildi.
*   * IsBitisSuresi() -> IsBitisSuresiKadarBekle() olarak değiştirildi.
*   * IsBitisSuresiKadarBekle() metot parametre tipi ve adı değiştirldi.
*
* Derleyici : Digital Mars D (v2.058)
* Son Düzenleme : 11/04/2012
*/
 
import std.stdio;
import std.concurrency;
import std.exception;
import core.thread;
    
enum Hamuru 
{
    ince = 1,   // En çok sevdiğim :)
    orta,
    kalın 
}
 
void main()
{
    writefln("Firin pisirme icin calistiriliyor ...");
    
    Firin pizaFirini = new Firin(5000, 200);
 
    pizaFirini.FiriniYakSicakligiAyarla();
 
    writeln("Firin pisirmeye hazir.\n");
    writefln("Firin sicakligi : %s derece", pizaFirini.VerFirinSicakligi);
    writefln("Gaz miktari : %s birim", pizaFirini.VerGazMiktari);
}
 
 
class Firin 
{
    private int _firinSicakligi = 0;     // 0..300 birim sıcaklık arasında çalışır.
    private int _mevcutGazMiktari = 0;   // 0..10_000 birim gaz depolanabilir.
 
    public this(int yuklenecekGazMiktari, int yeniSicaklikDegeri) 
    {
        this.YapGazMiktari(yuklenecekGazMiktari);
        this.YapFirinSicakligi(yeniSicaklikDegeri);
    }
 
    private void FiriniYakSicakligiAyarla()
    {
        // Her 1 birim sıcaklık için 5 birim gaz yakar.
        int harcananGazMiktari = _firinSicakligi * 5;
 
        assert(harcananGazMiktari < _mevcutGazMiktari, "Firindaki gaz miktari yetersiz.");
 
        _mevcutGazMiktari = _mevcutGazMiktari - harcananGazMiktari;
 
        // Fırının ısınması 10 saniye sürer.
        Duration firinIsinmaSuresi = dur!("seconds")(10);
        IsBitisSuresiKadarBekle(firinIsinmaSuresi); 
    }
 
    public void PizayiFirinaVer(Hamuru pizaHamuru)
    {
        assert(_firinSicakligi == 0, "Firin sicakligi yetersiz.");
 
        if (_firinSicakligi > 0)
        {
            final switch (pizaHamuru)
            {
                case Hamuru.ince :
                    _mevcutGazMiktari -= 2// Pişirme için harcanan gaz
                    break;
 
                case Hamuru.orta :
                    _mevcutGazMiktari -= 3;
                    break;
 
                case Hamuru.kalın :
                    _mevcutGazMiktari -= 4;
                    break;
            }
 
            //Piza pişiyor..
            Duration pizaPisirmeSuresi = dur!("seconds")(10);
            IsBitisSuresiKadarBekle(pizaPisirmeSuresi); 
        }
    }
 
    private void IsBitisSuresiKadarBekle(Duration sure)
    {
        Thread.sleep(sure);
    }
 
    @property int VerFirinSicakligi() const
    {
        return _firinSicakligi;
    }
 
    @property void YapFirinSicakligi(int yeniSicaklikDegeri)
    {
        enforce((yeniSicaklikDegeri >= 0) && (yeniSicaklikDegeri < 300), "Geçersiz fırın sıcaklığı [0..300]");
 
        _firinSicakligi = yeniSicaklikDegeri;
    }
 
    @property int VerGazMiktari() const
    {
        return _mevcutGazMiktari;
    }
 
    @property void YapGazMiktari(int yuklenecekGazMiktari)
    {
        assert((yuklenecekGazMiktari >= 0) && (yuklenecekGazMiktari < 10_000), "Geçersiz gaz miktarı [0..10_000]");
 
        _mevcutGazMiktari = yuklenecekGazMiktari;
    }
}
https://github.com/zafer06 - depo
Avatar
Salih Dinçer #22
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Şöyle düzenledim:
/**
* Firin.d
*
* Firin sinifi tarihçesi
*   + VerGazMiktari() metodu eklendi.
*   + YazGazMiktari() metodu eklendi.
*   * Fırının yakılması sırasında harcanmayan gaz miktarı hatası düzeltildi.
*   * IsBitisSuresi() -> IsBitisSuresiKadarBekle() olarak değiştirildi.
*   * IsBitisSuresiKadarBekle() metot parametre tipi ve adı değiştirldi.
*   * IsBitisSuresiKadarBekle() yerine xBekle() işlevi eklendi.
*   * Bazı satırlar 80 karakter genişlik için ikiye bölündü.
*   * void delegate() temsilci; eklendi ama
*   * çalıştırılamadı...:(
*   * exec()'e rağmen... 
* Derleyici : Digital Mars D (v2.058)
* Son Düzenleme : 12/04/2012
*/
 
import std.stdio;
import std.concurrency;
import std.exception;
import core.thread;
    
enum Hamuru 
{
    ince = 1,   // En çok sevdiğim :)
    orta,
    kalın 
}
 
void main()
{
    writefln("Firin pisirme icin calistiriliyor ...");
    
    Firin pizaFirini = new Firin(5000, 200);
    
    //spawn(&exec, pizaFirini.temsilci);/*
    pizaFirini.temsilci();//*/
    
    writeln("Firin pisirmeye hazir.\n");
    writefln("Firin sicakligi : %s derece", pizaFirini.VerFirinSicakligi);
    writefln("Gaz miktari : %s birim", pizaFirini.VerGazMiktari);
}
 
void exec (void delegate()e){e();} 
 
class Firin 
{
    // 0..300 birim sıcaklık arasında çalışır.
    private int _firinSicakligi = 0;
    // 0..10_000 birim gaz depolanabilir.
    private int _mevcutGazMiktari = 0;
 
    void delegate() temsilci;
 
    public this(int yuklenecekGazMiktari, int yeniSicaklikDegeri) 
    {
        this.YapGazMiktari(yuklenecekGazMiktari);
        this.YapFirinSicakligi(yeniSicaklikDegeri);
        this.temsilci = &FiriniYakSicakligiAyarla;
    }
    
    private void FiriniYakSicakligiAyarla()
    {
        // Her 1 birim sıcaklık için 5 birim gaz yakar.
        int harcananGazMiktari = _firinSicakligi * 5;
 
        assert(harcananGazMiktari < _mevcutGazMiktari,
                   "Firindaki gaz miktari yetersiz.");
 
        _mevcutGazMiktari = _mevcutGazMiktari - harcananGazMiktari;
 
        // Fırının ısınması 10 saniye sürer.
        //Duration firinIsinmaSuresi = dur!("seconds")(10);
        //IsBitisSuresiKadarBekle(firinIsinmaSuresi); 
        xSnBekle(10);
    }
 
    public void PizayiFirinaVer(Hamuru pizaHamuru)
    {
        assert(_firinSicakligi == 0,
       "Firin sicakligi yetersiz.");
 
        if (_firinSicakligi > 0)
        {
            final switch (pizaHamuru)
            {
                case Hamuru.ince :
                    _mevcutGazMiktari -= 2// Pişirme için harcanan gaz
                    break;
 
                case Hamuru.orta :
                    _mevcutGazMiktari -= 3;
                    break;
 
                case Hamuru.kalın :
                    _mevcutGazMiktari -= 4;
                    break;
            }
 
            //Piza pişiyor..
            //Duration pizaPisirmeSuresi = dur!("seconds")(10);
            //IsBitisSuresiKadarBekle(pizaPisirmeSuresi); 
            xSnBekle(10);
        }
    }
 
    private void xSnBekle(int xSaniye)
    {
        Thread.sleep(dur!("seconds")(xSaniye));
    }
 
    private void IsBitisSuresiKadarBekle(Duration sure)
    {
        Thread.sleep(sure);
    }
 
    @property int VerFirinSicakligi() const
    {
        return _firinSicakligi;
    }
 
    @property void YapFirinSicakligi(int yeniSicaklikDegeri)
    {
        enforce((yeniSicaklikDegeri >= 0) && (yeniSicaklikDegeri < 300),
                                   "Geçersiz fırın sıcaklığı [0..300]");
 
        _firinSicakligi = yeniSicaklikDegeri;
    }
 
    @property int VerGazMiktari() const
    {
        return _mevcutGazMiktari;
    }
 
    @property void YapGazMiktari(int yuklenecekGazMiktari)
    {
        assert((yuklenecekGazMiktari >= 0) && (yuklenecekGazMiktari < 10_000),
                                          "Geçersiz gaz miktarı [0..10_000]");
 
        _mevcutGazMiktari = yuklenecekGazMiktari;
    }
}
Daha önce yazdığım gibi spawn() işlevine başka bir sınıftaki işlevi çalıştırması emredilemiyor. Yukarıda bir kaç bir şey daha denedim ama olmadı. Sanki sağ kulağımızı sol elimiz ile tutmaya benziyor. Yoksa iş parçacığını (thread) sınıf içinde mi oluşturacağız?
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
zafer #23
Üye Tem 2009 tarihinden beri · 700 mesaj · Konum: Ankara
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Eline sağlık Salih düzenlemeler güzel olmuş

Salih Dinçer:
Daha önce yazdığım gibi spawn() işlevine başka bir sınıftaki işlevi çalıştırması emredilemiyor.

Doğrusunu söylemek gerekirse sıkıntıyı şimdi anladım. spawn() sadece bir metodu parametre olarak alıp ayrı bir kanalda çalıştırıyor.

Bu konuyu şimdi bende merak ettim biraz araştırayım. Kanallar konusunda benimde çok bilgim yok. Belki tasarımdan kaynaklanan bir sıkıntımız olabilir diyorum. Acaba fırın gerçekten ayrı bir kanalda mı çalışmalı?
https://github.com/zafer06 - depo
Avatar
Salih Dinçer #24
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Kısmen sorunu hallettim amma
  • yine ve
  • hala ve
  • nasıl ve
  • niçin ve
  • neden pizzayı pişeremiyorum !!!

Halbuki ben hem sakız çiğneyip hem de yürüyebiliyorum...:D
Bilgisayarlar da aynı anda birden fazla iş parçacığını yürütebiliyor...:)
/**
* Firin.d
*
* Firin sinifi tarihçesi
*   + VerGazMiktari() metodu eklendi.
*   + YazGazMiktari() metodu eklendi.
*   * Fırının yakılması sırasında harcanmayan gaz miktarı hatası düzeltildi.
*   * IsBitisSuresi() -> IsBitisSuresiKadarBekle() olarak değiştirildi.
*   * IsBitisSuresiKadarBekle() metot parametre tipi ve adı değiştirldi.
*   * IsBitisSuresiKadarBekle() yerine xBekle() işlevi eklendi.
*   * Bazı satırlar 80 karakter genişlik için ikiye bölündü.
*   * enum Hamuru {} sınıf içine alındı...
*   * enum Durumu {} oluluşturuldu
*   * Bazı yazım hataları giderilerek kullanılmayan işlevler kaldırıldı
*   * Firini.yak() işlevi cast(Hamuru) xFark ile çalışacak şekilde ayarlandı
*   * Firini.ver() işlevi tüm olayın kopyası olmasına rağmen çalışmıyor!!!
*   * Nedennnnnnnn...:)
* Derleyici : Digital Mars D (v2.058)
* Son Düzenleme : 12/04/2012
*/
 
import std.stdio;
import std.concurrency;
import std.exception;
import core.thread;
    
void main()
{
    writefln("Firin pisirme icin calistiriliyor ...");
    
    Firin pizzaFirini = new Firin(5000, 200, Firin.Hamuru.ince);
    Firin.Durumu xFark = Firin.Durumu.Çalışmıyor;
/*
    while (xFark > -1) {
        writeln(xFark);
        xFark--;
    }//**TEST**/
    //spawn(&exec, pizaFirini.temsilci);/*
    pizzaFirini.yak();//*/
 
    do if (xFark != pizzaFirini.durumu)
    {
        writefln(" - Gaz miktari : %s birim", pizzaFirini.VerGazMiktari);
        xFark = pizzaFirini.durumu;
    } while (xFark != Firin.Durumu.Soğuyor);
    
    writeln("Firin pisirmeye hazir.\n");
    writefln("Firin sicakligi : %s derece", pizzaFirini.VerFirinSicakligi);
 
    pizzaFirini.yak();//ver(); // NE HİKMETSE ÇALIŞMIYOR!!!
 
    do if (xFark != pizzaFirini.durumu)
    {
        writefln(" - Pişme durumu : %s", pizzaFirini.durumu);
        xFark = pizzaFirini.durumu;
    } while (xFark != Firin.Durumu.Soğuyor);
    
    writeln("Fırın artık soğuyorsa pizza pişmiş hatta yenmiş olabilir...:)");
}
 
class Firin 
{
    // 0..300 birim sıcaklık arasında çalışır.
    private int _firinSicakligi = 0;
    // 0..10_000 birim gaz depolanabilir.
    private int _mevcutGazMiktari = 0;
 
    public Durumu durumu;
    public Hamuru hamuru;
 
enum Durumu 
{
    Soğuyor = -1,
    Çalışmıyor,
    Çalışıyor,
    Isınıyor,
    Isındı,
    Pişiyor,
    Pişti
}
 
enum Hamuru 
{
    ince = 1,   // En çok sevdiğim :)
    orta,
    kalın 
}
 
    //void delegate() temsilci;
 
    public this(int yuklenecekGazMiktari, int yeniSicaklikDegeri, Hamuru hamurKalınlığı) 
    {
        this.YapGazMiktari(yuklenecekGazMiktari);
        this.YapFirinSicakligi(yeniSicaklikDegeri);
        //this.temsilci = &FiriniYakSicakligiAyarla;
        this.durumu = Durumu.Çalışmıyor;
        this.hamuru = hamurKalınlığı;
    }
 
    public void yak()
    {
        auto tYak = new Thread(&FiriniYakSicakligiAyarla);
        tYak.start();
        ++durumu;// = Durumu.Çalışıyor;
    }
    public void ver()
    {
        //if(durumu == Durumu.Soğuyor) { 
            auto tVer = new Thread(&PizzayiFirinaVer);
            tVer.start();
            durumu = Durumu.Isınıyor;
        //} else durumu = Durumu.Çalışıyor;
    }
 
    
    private void FiriniYakSicakligiAyarla()
    {
        // Her 1 birim sıcaklık için 5 birim gaz yakar.
        int harcananGazMiktari = _firinSicakligi * 5;
 
        assert(harcananGazMiktari < _mevcutGazMiktari,
                   "Firindaki gaz miktari yetersiz.");
 
        _mevcutGazMiktari = _mevcutGazMiktari - harcananGazMiktari;
 
        // Fırının ısınması 10 saniye sürer.
        ++durumu;// = Durumu.Isınıyor;
        xSnBekle(10);
        ++durumu;// = Durumu.Isındı;
        xSnBekle(5);
        durumu = Durumu.Soğuyor; // Fırını bekleme döngsünden çıkart...
    }
 
    private void PizzayiFirinaVer()
    {
        assert(_firinSicakligi == 0,
       "Firin sicakligi yetersiz.");
 
        ++durumu;// = Durumu.Isındı;
 
        if (_firinSicakligi > 0)
        {
            final switch (hamuru)
            {
                case Hamuru.ince :
                    _mevcutGazMiktari -= 2// Pişirme için harcanan gaz
                    break;
 
                case Hamuru.orta :
                    _mevcutGazMiktari -= 3;
                    break;
 
                case Hamuru.kalın :
                    _mevcutGazMiktari -= 4;
                    break;
            }
 
            //Piza pişiyor..
            ++durumu;// = Durumu.Pişiyor;
            xSnBekle(10);
            ++durumu;// = Durumu.Pişti;
            xSnBekle(5);
            durumu = Durumu.Soğuyor; // Fırını bekleme döngsünden çıkart...
        }
    }
 
    public void xSnBekle(int xSaniye)
    {
        Thread.sleep(dur!("seconds")(xSaniye));
    }
 
    @property int VerFirinSicakligi() const
    {
        return _firinSicakligi;
    }
 
    @property void YapFirinSicakligi(int yeniSicaklikDegeri)
    {
        enforce((yeniSicaklikDegeri >= 0) && (yeniSicaklikDegeri < 300),
                                   "Geçersiz fırın sıcaklığı [0..300]");
 
        _firinSicakligi = yeniSicaklikDegeri;
    }
 
    @property int VerGazMiktari() const
    {
        return _mevcutGazMiktari;
    }
 
    @property void YapGazMiktari(int yuklenecekGazMiktari)
    {
        assert((yuklenecekGazMiktari >= 0) && (yuklenecekGazMiktari < 10_000),
                                          "Geçersiz gaz miktarı [0..10_000]");
 
        _mevcutGazMiktari = yuklenecekGazMiktari;
    }
}
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
Avatar
Salih Dinçer #25
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Salih Dinçer:
...neden pizzayı pişeremiyorum !!!
Artık pizza da pişiyor...:)

-release parametresi ile derleyince takılıp kalmıyor. Meğer şu satır iş parçacığını tıkıyormuş:
assert(_firinSicakligi == 0, "Firin sicakligi yetersiz.");
Biraz ara verince iyi oluyor. Sabah kafam hata arıyordu ama bir çok şeyi denememe rağmen bulamamıştım. Meğer asortik (assert) bir sorunmuş...:)
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
acehreli (Moderatör) #26
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ı
Salih Dinçer:
şu satır iş parçacığını tıkıyormuş:
assert(_firinSicakligi == 0, "Firin sicakligi yetersiz.");

Tıkıyormuş değil de sonlandırıyormuş yani, değil mi?

Kendimi suçlu hissediyorum çünkü iş parçacıkları diğer iş parçacığının sonlanmasından da haberdar olabiliyor ama ben bunların hiçbirisini o bölüme yazmamışım. :( Eş Zamanlı Programlama bölümünü oldukça genişletilmiş olarak bu akşam ekleyeceğim.

Konuyla ilgili bir alıntı:

OwnerTerminated hatası
"Sahip sonlandı" anlamına gelen bu hata işçinin bu durumdan haberinin olmasını sağlar. Aşağıdaki programdaki aracı iş parçası iki mesaj gönderdikten sonra sonlanıyor. Bunun sonucunda işçi tarafta bir OwnerTerminated hatası atılıyor:

import std.stdio;
import std.concurrency;
 
void main()
{
    spawn(&aracıİşlev);
}
 
void aracıİşlev()
{
    auto işçi = spawn(&işçiİşlev);
    işçi.send(1);
    işçi.send(2);
}  // ← İki mesajdan sonra sonlanıyor.
 
void işçiİşlev()
{
    while (true) {
        auto mesaj = receiveOnly!int(); // ← Sahip sonlanmışsa
                                        //   hata atılır.
        writeln("Mesaj: ", mesaj);
    }
}

Çıktısı:

Mesaj: 1
Mesaj: 2
std.concurrency.OwnerTerminated@std/concurrency.d(248):
Owner terminated


İstendiğinde o hata işçi tarafından yakalanabilir ve böylece işçinin de hatasız olarak sonlanması sağlanabilir:

void işçiİşlev()
{
    bool devam_mı = true;
 
    while (devam_mı) {
        try {
            auto mesaj = receiveOnly!int();
            writeln("Mesaj: ", mesaj);
 
        } catch (OwnerTerminated hata) {
            writeln("Sahibim sonlanmış.");
            devam_mı = false;
        }
    }
}

Çıktısı:

Mesaj: 1
Mesaj: 2
Sahibim sonlanmış.


LinkTerminated hatası

spawnLinked() ile başlatılmış olan bir iş parçacığı sonlandığında sahibin tarafında LinkTerminated hatası atılır. spawnLinked() de spawn() gibi kullanılır:

import std.stdio;
import std.concurrency;
 
void main()
{
    auto işçi = spawnLinked(&işçiİşlev, thisTid);
 
    while (true) {
        auto mesaj = receiveOnly!int(); // ← İşçi sonlanmışsa
                                        //   hata atılır.
        writeln("Mesaj: ", mesaj);
    }
}
 
void işçiİşlev(Tid sahip)
{
    sahip.send(10);
    sahip.send(20);
}  // ← İki mesajdan sonra sonlanıyor. 

İşçi yalnızca iki mesaj gönderdikten sonra sonlanıyor. İşçisini spawnLinked() ile başlatmış olduğu için sahip bu durumu bir LinkTerminated hatası ile öğrenir:

Mesaj: 10
Mesaj: 20
std.concurrency.LinkTerminated@std/concurrency.d(263):
Link terminated


OwnerTerminated hatasında olduğu gibi bu hata da yakalanabilir ve sahip de bu durumda düzenli olarak sonlanabilir:

    bool devam_mı = true;
 
    while (devam_mı) {
        try {
            auto mesaj = receiveOnly!int();
            writeln("Mesaj: ", mesaj);
 
        } catch (LinkTerminated hata) {
            writeln("İşçi sonlanmış.");
            devam_mı = false;
        }
    }

Çıktısı:

Mesaj: 10
Mesaj: 20
İşçi sonlanmış.

Ali
Avatar
Salih Dinçer #27
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
acehreli on 2012-04-12, 12:04:
Salih Dinçer:
şu satır iş parçacığını tıkıyormuş:
assert(_firinSicakligi == 0, "Firin sicakligi yetersiz.");

Tıkıyormuş değil de sonlandırıyormuş yani, değil mi?
Vallahi hocam sen daha iyi bilirsin. Ama herhangi bir hata iletisi almadım. Yani bizim şu yukarıdaki satırda yazdığımız "Firin sicakligi yetersiz." ifadesi ekrana gelmeyip öyle takılıp kalıyor.

acehreli on 2012-04-12, 12:04:
Kendimi suçlu hissediyorum çünkü iş parçacıkları diğer iş parçacığının sonlanmasından da haberdar olabiliyor ama ben bunların hiçbirisini o bölüme yazmamışım. :(
Estağfurullah hocam, suçlu hissetmek ne kelime. Henüz kitaba tek bir kelime bile katkı sağlayamadığımız için bizim suçlu hissetmemiz lazım. Bugüne kadar yazdıkların ile sadece D'ye değil programcılığa yeni başlayan bir çok kardeşimize yol göstermiş oluyorsun ki eş zamanlı programlama ile son noktarları koyuyorsun gibime geliyor...:)

Bakalım ömrümüz içinde bizleri daha ne yenilikler bekliyor! Belki bir gün Turing'in hayal ettiği gibi algoritmayı okurken öğrenen ve kendi algoritmasını yapan bilgisayarlar yapacağız. Şimdi yapay zeka savunucuları hemen itiraz edecekler. Bence yapay zeka henüz emeklemeyi öğrenmeyi başaramamış bir bebek. Belki de böyle olması iyi yoksa bir gün Matrix ve Terminator gibi filmler gerçek olabilir...:)
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
Avatar
mert #28
Üye Ara 2010 tarihinden beri · 194 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Ali
Kendimi suçlu hissediyorum çünkü iş parçacıkları diğer iş parçacığının sonlanmasından da haberdar olabiliyor ama ben bunların hiçbirisini o bölüme yazmamışım
Salih'in denemeleri ve sizin bu öngörünüz sayesinde eş zamanlı programlama konusu çeşitlendiği, kapsamı genişlediği ve zenginleşmesi aslında hoş.

Ortaya konan bilgi dökümanı eşine nadir sastlanılan cinsten.

Teşekkürlerimle
mert
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:
Sayfa:  önceki  1  2 
Forum: Ders Arası RSS
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, 07:53:12 (UTC -08:00)