April 10, 2012

Alıntı:

>

Neyse çok uzatmayayım, herhalde randomize factorünü hala kavrayamadım..

Kavranmış gibi algılanıyor buralardan ama ))

Bu arada Salih olgulara ilginç yaklaşıyorsun ve bu bizler için de öğretici. Teşekkür ederim.

Ali hocam yorgunluğunuza yorgunluk katttığım için kusuruma bakmayın yasaydı büyüktü derken. Söz telafi edeceğim İstanbul'a indiğinizde. Kahveleri mehmet efendi ve mahdumlarında içeriz diye umuyorum.

İyi sabahlar hepimize )

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

April 10, 2012

Alıntı (Ali Çehreli):

>

Alıntı (Salih Dinçer):

>

işlemci çok hızlı bir şekilde 'while('true')' kümesini işletmesi gerekmez miydi?
main() her bir receive()'de mesaj bekliyor onun için o da adım adım işliyor.
Bir dakikaaaa....:)

'receive()' işlevinde bir duraklama (sıralı işleme) söz konusu olduğunu yeni öğrendim. Öyleyse 1 ile 1000 ms. arasındaki küçük farklar ile çalışan iki motorumuz var ki bunların eş zamanlı çalışması belki de doğaldır. Sanırım anlayamadığım ve beni şaşırtan nokta işte burası ve sonunda (ohhh) anlamişem...:D

Mert'in motor devirleri ile ilgili örneğin çok benzedi. Bu durumda her iki motor (bilgisayar) da aynı şekilde tekliyor. Küçük bir sözleşme(espri) ile kapayım...:)

"İşbu, bilgi işlem dünyasında yer alan bir 'receive()' işlevi (bundan sonra KORUYUCU olarak anılacaktır) tüm düzeni korur. Tüm iş parçacıkları (thread) birbiriyle KORUYUCU tarafından haberleşirler. Böylece herhangi bir karmaşa'*****' meydana gelmez."

'*****' Gerçi writef ve/veya writefln'nin bu KORUYUCU sistem üzerinde bozucu bir etkisi olduğunu tespit ettim. Özellikle Linux'da çok kritik hatalara neden oluyor. Mümkün olduğunca 'writeln()' kullanmanızı salık veririm. Sanki D programlama dili Windows'da daha kararlı çalışıyor. Bir de Mac'ler de denemeli...

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

April 10, 2012

Alıntı (mert):

>

Alıntı:

>

Neyse çok uzatmayayım, herhalde randomize factorünü hala kavrayamadım..

Kavranmış gibi algılanıyor buralardan ama ))

Bu arada Salih olgulara ilginç yaklaşıyorsun ve bu bizler için de öğretici. Teşekkür ederim.

Ali hocam yorgunluğunuza yorgunluk katttığım için kusuruma bakmayın yasaydı büyüktü derken. Söz telafi edeceğim İstanbul'a indiğinizde. Kahveleri mehmet efendi ve mahdumlarında içeriz diye umuyorum.

İyi sabahlar hepimize )

Hayırlı sabahlar, iyi bir çarşamba günü diliyorum...:)

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

April 10, 2012

Alıntı (Salih Dinçer):

>

Sonuç bana şaşırtıcı geldi çünkü yazılımlar çok az bir farkla (CTRL+C yapış zamanından anlayabilirsiniz) eş zamanlı gidiyordu! Bu nasıl bir rasgelelik veya eş zamanlı çalışmadır anlamadım.

Tekrar tekrar okudum ama neye şaşırdığını ve neyi sorduğunu anlayamadım. :(

Alıntı:

>

Bir de şu kodu denemelisiniz...

Derledim ve çalıştırdım ama neye bakmam gerektiğini bilemiyorum. Ne bekliyordun? Ne oldu? :)

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

April 10, 2012

Alıntı (acehreli):

>

Alıntı (Salih Dinçer):

>

Son bir kaç satır ise uyku zamanına uygun bir şekilde çıkmakta:
': : :
812 ms - birinci() x 97 kez girdi/çıktı!
98 ms - ikinci() x 97 kez girdi/çıktı!
846 ms - birinci() x 98 kez girdi/çıktı!
553 ms - ikinci() x 98 kez girdi/çıktı!
799 ms - birinci() x 99 kez girdi/çıktı!
915 ms - ikinci() x 99 kez girdi/çıktı!
555 ms - birinci() x 100 kez girdi/çıktı!
736 ms - ikinci() x 100 kez girdi/çıktı!'

Evet, ben sınırıma vurdum galiba çünkü hâlâ sorun ne anlayamadım. Yukarıdaki çıktıdan ne anlamak gerekiyor? Bir yanlışlığı mı gösteriyorlar? Benim gördüğüm, ne kadar süreyle uyuyacaklarını bildiriyorlar. Bunda ne gariplik var?

Alıntı:

>

işlemci çok hızlı bir şekilde 'while('true')' kümesini işletmesi gerekmez miydi?

main() her bir receive()'de mesaj bekliyor onun için o da adım adım işliyor.
Hocam, ben de sınıra vurmaya başladım...:)

Şaka bir yana; uzatmak istemiyordum ama eğer 'receive()' işlevinde bekliyorsa neden aşağıdaki kod şakır şakır çalışıyor?

/*Lütfen önceki sayfada naklettiğim kod ile birlikte kullanın */
void main() {
   shared auto xSay = Say();
   Tid ikinciTid, birinciTid;
   int loop = 0;

   while (true) {
       birinciTid = spawn(&birinci, thisTid, &xSay);

       send(birinciTid, uniform(1, 1000));
       receive ((string xDurum) { writef("%s\n", xDurum); });

       ikinciTid = spawn(&ikinci, thisTid, &xSay);

       send(ikinciTid, uniform(1, 1000));
       receive ((string xDurum) { writef("%s\n", xDurum); });

      ++loop;
   }
   writef("%d", loop);
}

Çıktısı:
': : :

  • birinci() x 504 kez girdi/çıktı!
    949 ms
  • ikinci() x 506 kez girdi/çıktı!
    176 ms
  • ikinci() x 507 kez girdi/çıktı!
  • ikinci() x 508 kez girdi/çıktı!
  • birinci() x 505 kez girdi/çıktı!
    198 ms
    163 ms
    27 ms
  • ikinci() x 509 kez girdi/çıktı!
  • ikinci() x 510 kez girdi/çıktı!
    676 ms
    ^C
    birinci() x 134753112 kez girdi...
    /usr/bin/d.sh: satır 10: 6879 Parçalama arızası ./$file_name $'

Ayrıca ekrana yazılan çıktıyı 'writeln()' ile de denedim ve** 'scope('exit')' i**çindeki gereksiz 'send()' işlevini kaldırdım değişen bir şey yok. Aslında her çalıştırışta program farklı şekillerde çöküyor. Ama döngü içinde aşırı yüklenme olduğundan bu meydana geliyor. Sizin bilgisayarınızda daha farklı çalıştırılabilir. Sanırım bu tür birden fazla iş parçacığı için flipFlop tarzı bir kontrol mekanizması şartmış.

Başarılar...

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

April 10, 2012

Alıntı (Salih Dinçer):

>

1000 girip/çıkmaya kadar aynı yönde ilerlediler. Ancak sonra 5, 10 derken 3000'lerde 15 fark vardı. Şimdi ise 10 binlerde ve aradaki fark 75 ki bana bu ilginç geliyor.

15/3000 = Binde 5
75/10000 = Binde 7.5

İstatistiksel hata payı sayılır onlar. Zaten her an için eşit olsalardı da rasgele diyemezdik. :)

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

April 10, 2012

Alıntı (Salih Dinçer):

>

Aksine bu fark (hata payı değil) çok küçük!

Deney sayısı arttıkça ortalama değere oturması gerekir.

Alıntı:

>
  • Bilgisayardan 1 ila 1000 arasında sayı tutması isteniyor. (aslında iki çünkü her programda iki işlev var)

Yani yeterince deney yapıldığında ortalamaları 500'e oturacak olan [1,999] aralığında sayılar var.

Alıntı:

>
  • Kuramsal olarak birinci bilgisayar en küçük 1'i seçebilirken,
  • İkinci bilgisayar en büyüğünü de seçebilir...

Evet. Onun olasılığı ile tam tersinin olma olasılığı da aynı.

Alıntı:

>

Bu şu demek: Başlangıçta aralarındaki fark çok büyük olmalı...

Doğru. Tek deney yaptığımızda beklenen ortalama değerden 499 değer uzağa bile düşebiliriz.

Alıntı:

>

Ancaaaak, bu spawnTest örneğinde neredeyse başa baş gidiyorlar ve sonra doğal olarak araları açılıyor...:)

Herhalde ortalıkta çok fazla kavram dolaştığı için başa baş gidenin ne olduğunu anlayamıyorum. Sayılar mı başa baş? Ortalamaları mı?

Şimdi aklıma bir şey geliyor: Acaba writefln() kullanmadığın için standart çıkış "flush edilmiyor" da sen iş parçacıklarının aynı anda gidiyorlar mı diye gözlemliyorsun?

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

April 10, 2012

Alıntı (Salih Dinçer):

>

Son bir kaç satır ise uyku zamanına uygun bir şekilde çıkmakta:
': : :
812 ms - birinci() x 97 kez girdi/çıktı!
98 ms - ikinci() x 97 kez girdi/çıktı!
846 ms - birinci() x 98 kez girdi/çıktı!
553 ms - ikinci() x 98 kez girdi/çıktı!
799 ms - birinci() x 99 kez girdi/çıktı!
915 ms - ikinci() x 99 kez girdi/çıktı!
555 ms - birinci() x 100 kez girdi/çıktı!
736 ms - ikinci() x 100 kez girdi/çıktı!'

Evet, ben sınırıma vurdum galiba çünkü hâlâ sorun ne anlayamadım. Yukarıdaki çıktıdan ne anlamak gerekiyor? Bir yanlışlığı mı gösteriyorlar? Benim gördüğüm, ne kadar süreyle uyuyacaklarını bildiriyorlar. Bunda ne gariplik var?

Alıntı:

>

işlemci çok hızlı bir şekilde 'while('true')' kümesini işletmesi gerekmez miydi?

main() her bir receive()'de mesaj bekliyor onun için o da adım adım işliyor.

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

April 11, 2012

Umarım başka arkadaşlar anlamışlardır.

Çok farklı konulara dokunan bir örnek olduğu için neresiyle ilgili düşüneceğimi bile anlayamadım.

  • Rasgelelikle ilgili bir gariplik mi var?

  • Rasgele bir süre uyumaları beklendiği halde aynı anda mı uyuyup uyanıyorlar?

  • Sonsuz sayıda iş parçacığı başlatıp sonlandırarak bu modülün sınırlarını mı anlamaya çalışıyoruz?

  • Doğrudan veri paylaşımının riskli olduğunu duyduğumuz halde belki de aynı yapının farklı üyelerine dokunulduğu zaman sorun olmadığını mı görmeye çalışıyoruz?

Bu programda çok fazla sayıda ve ilgisiz konu geçtiği için ve "şu çıktıya bakın" anlamında açıklama geldiği için ben hiçbir şey anlamıyorum.

Alıntı:

>

ama eğer receive() işlevinde bekliyorsa neden aşağıdaki kod şakır şakır çalışıyor?

Şakır şakır çalışmayla ne kastediyorsun? Evet receive() işlevinde bekler ama bu neden şakır şakır çalışmaya engel olsun? receive() işlevinde bekler, bir iş parçacığının gönderdiği mesajı alır ve işine devam eder.

Ondan sonra çıktısında parçalanma arızası gösteriyorsun. Kafam iyice karışıyor. Yani şakır şakır çalışıyor derken parçalanma arızasını mı kastediyorsun?

Ben bu kafa karışıklığıyla durumda olaydan küçük adımlarla uzaklaşıyorum... :)

Alıntı:

>

Ama döngü içinde aşırı yüklenme olduğundan bu meydana geliyor.

Belki de posta kutusunun fazla büyümesinden oluyordur.

Tam şu sırada Eş Zamanlı Programlama bölümünü bir yandan İngilizce'ye çeviriyorum, bir yandan da Türkçe'sini gözden geçiriyorum. Mesajlaşma ile veri paylaşımını iki bölüm olarak ayırmaya karar verdim ve std.concurrency modülünün diğer olanaklarını da Mesajlaşma bölümüne eklemeye karar verdim.

Oraya şöyle bir örnek eklemek üzereyim:

import std.concurrency;
import core.thread;

void işçiİşlev(Tid sahip)
{
   while (true) {
       sahip.send(42);
   }
}

void main()
{
   spawn(&işçiİşlev, thisTid);

   while (true) {
       receive(
           (int mesaj) {
               Thread.sleep(dur!"seconds"(1));
           });
   }
}

O programdaki işçi sahibe sürekli olarak mesaj gönderiyor. Sahip ise mesajları posta kutusundan çekip kullanmakta ona göre yavaş kalıyor. Sonuçta posta kutusu şiştikçe şişer.

Eğer senin sorunun da posta kutusunun doluluğu ile ilgiliyse setMaxMailboxSize() işlevine ihtiyacın var. Bunun çözümü için main'in en başına şu satırı ekleyebilirsin:

   setMaxMailboxSize(thisTid, 1000, OnCrowding.block);

O satır, ana iş parçacığının posta kutusunun uzunluğunu 1000 olarak sınırlıyor. Üçüncü parametre için üç seçenek var:

  • OnCrowding.block: Posta kutusu doluysa gönderenler mesaja yer açılana kadar beklerler.

  • OnCrowding.ignore: Posta kutusu doluysa mesaj gözardı edilir.

  • OnCrowding.throwException: Posta kutusu doluysa mesaj gönderilirken hata atılır. Ama hata mesajı gönderen tarafında atıldığı için try-catch bloğunun işçi tarafında olması gerekiyor:

import std.concurrency;
import core.thread;

void işçiİşlev(Tid sahip)
{
   while (true) {
       try {
           sahip.send(42);

       } catch (MailboxFull hata) {
           /* Gönderemedim; biraz sonra tekrar denerim. */
           Thread.sleep(dur!"msecs"(1));
       }
   }
}

void main()
{
   setMaxMailboxSize(thisTid, 1000, OnCrowding.throwException);

   spawn(&işçiİşlev, thisTid);

   while (true) {
       receive(
           (int mesaj) {
               Thread.sleep(dur!"seconds"(1));
           });
   }
}

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

April 19, 2012

Hocam, bazı şeyleri tam kavramadan cevabımı bir hafta geciktirdim. Sorduğun sorularda haklısın tabi. Burada biraz Zihni Sinir bir olay var ve açıklayamıyorum...:D

Olay aslında basit, rasgele süre (saniye) boyunca 2 işlev (iş parçacağı) çalışıyor. Bu tek programda (exe'de) her şey normal görünüyor ama iş ikinci bir programı çalıştırdığınızda (etti 4 iş parçacığı) rasgelelikten uzaklaşıp birbirleriyle yakın doğruda (-bknz. önceki sayfadaki çizelge) ilerliyor. Yani soruna programcılık mantığıyla değil de biraz bilimsel ve şüpheci mantıkla bakmak gerkiyor; neden?

Biraz cevap olsun diye geçen haftaki kodları biraz sadeleştirdim ve birbirini bekleyen send/receive ile flip/flop mekanizmalarını kaldırdım. Sonuçlar ne hikmetse yine aynı!

/*
   sleepTest2s.d (19.04.2012)
*/

import core.thread, std.concurrency;
import std.random, std.stdio: writeln;

struct birYapı { int Sayımı, Beklemesi; }
shared birYapı birincinin, ikincinin;

void birinci (Tid anaKimlik) {
   scope(exit) {
       writeln(" - birinci() x ", ++birincinin.Sayımı, " kez girdi...");
       send(anaKimlik, 1);
   }
   writeln("Ben (1.) birinciyim ve ", birincinin.Beklemesi,
           " saniye beklemeliyim!");

   Thread.sleep(dur!"seconds"(birincinin.Beklemesi));
}

void ikinci (Tid anaKimlik) {
   scope(exit) {
       writeln(" - ikinci() x ", ++ikincinin.Sayımı, " kez girdi...");
       send(anaKimlik, 2);
   }
   writeln("Ben (2.) ikinciyim ve ", ikincinin.Beklemesi,
           " saniye beklemeliyim!");

   Thread.sleep(dur!"seconds"(ikincinin.Beklemesi));
}

void main() {
   auto rasgele = () => uniform(1, 10);

   birincinin.Beklemesi = rasgele();
   spawn(&birinci, thisTid);

   ikincinin.Beklemesi = rasgele();
   spawn(&ikinci, thisTid);

   while (true) {
       final switch (receiveOnly!int()) {
           case 1:
                   birincinin.Beklemesi = rasgele();
                   spawn(&birinci, thisTid);
               break;

           case 2:
                   ikincinin.Beklemesi = rasgele();
                   spawn(&ikinci, thisTid);
               break;
       }
   }
}

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]