Bu konu 2017'de şurada tartışılmış ve o kadar lezetli ki anlatamam! Türkçe kitaptan alıntılanan ve Ali hoca tarafından geliştirilen bu kod kendini anlatsın... 😀
Hocam izninle, bu leziz kodu biraz (sınıf içine alarak, temsilci kullanarak ve birkaç değişken ismiyle oynayarak) değiştirdim:
import std.conv, std.string, std.stdio;
import core.thread, core.sync.mutex;
shared struct Düğüm
{
int eleman;
Düğüm * sonraki;
size_t length() const
{
return 1 + (sonraki ? sonraki.length : 0);
}
string toString() const
{
string result = to!string(eleman);
if (sonraki)
{
result ~= "\n" ~ to!string(*sonraki);
}
return result;
}
}
shared class Liste
{
Düğüm * baş;
void başınaEkle(int eleman)
{
baş = new shared(Düğüm)(eleman, baş);
}
void ekle(int threadNumarası, Mutex mutex)
{
const baş = threadNumarası * elemanAdedi;
const son = baş + elemanAdedi;
foreach(sayı; baş .. son)
{
{
scope(exit) mutex.unlock();
mutex.lock();
başınaEkle(sayı);
}
Thread.sleep(5.msecs);
}
}
string listele() const
{
auto result = baş ? to!string(*baş) : "";
return result.format!"%s";
}
size_t length() const
{
return baş ? baş.length : 0;
}
}
enum işParçacığıAdedi = 4;
enum elemanAdedi = 4;
void main()
{
shared s = new Liste();
auto mutex = new Mutex();
Thread[] işçiler;
foreach(t; 0 .. işParçacığıAdedi)
{
/* Orijinali:
auto işçiYap(int threadNumarası) {
return new Thread(
() => s.ekle(threadNumarası, mutex)
);} /*/
auto işçiYap(int threadNumarası)
{
return new Thread(delegate()
{
s.ekle(threadNumarası, mutex);
});
} //*/
işçiler ~= işçiYap(t);
}
foreach (işçi; işçiler)
{
işçi.start();
}
thread_joinAll();
// İşlerini bitirmelerini bekliyoruz...
writefln("%s adet eleman olmalı",
işParçacığıAdedi * elemanAdedi);
writefln("%s adet eleman var:\n%s",
s.length, s.listele);
} // araştır: multi threaded circular buffer