Transcript Threads

İş Parçacıkları
Thread(s)
Bir
çok
geliştirici
programlarını
doğrusal(linear) bir şekilde oluşturmaktadır.
Böyle bir durumda tek bir processin işini
bitirmesi beklenmekte ve ardından bir sonraki
kod parçasına geçilmektedir.
Günümüzde ise bu şekilde(tek process tek
thread) olduğu yaklaşım sınırlılıklara sahiptir.
İş Parçacığı
(Thread)
İş parçacığı, processin en küçük yürütme
birimidir. Bir processin çok sayıda threadi
olabilir.
Her bir thread farklı bir işlemcide veya
işlemcinin çekirdeğinde icra edilebilir.
Çoklu İş Parçacıkları
(Multiple Threads)
Bir çok metodu arka planda System.Threading
namespace’ini
kullanarak
çalıştırmak
mümkündür.
Bu isim alanı içerisinde kullanılan metot ise
“ThreadPool.QueueUserWorkItem” dır.
Thread Havuzu
(ThreadPool)
class Program
{
static void Main(string[] args)
{
ThreadPool.QueueUserWorkItem(ThreadProc);
Console.WriteLine("Ana thread işlem yapıyor ve ardından uyumakta");
Thread.Sleep(5000);
Console.WriteLine("Ana threadten çıkılıyor");
}
static void ThreadProc(object stateinfo)
{
Console.WriteLine("Thread çalışıyor");
}
}
class Program
{
static void Main(string[] args)
{
string state = "Merhaba Bilgisayar Mühendisliği“;
ThreadPool.QueueUserWorkItem(ThreadProc,state);
Console.WriteLine("Ana thread işlem yapıyor ve ardından
uyumakta");
Thread.Sleep(5000);
Console.WriteLine("Ana threadten çıkılıyor");
}
static void ThreadProc(object stateinfo)
{
Console.WriteLine("Gelen ifade:"+stateinfo.ToString());
}
}
Eğer threadlerin eş zamanlı olarak çalışması
gerekiyorsa, ThreadPool.QueueUserWorkItem
metodu bir çok defa çağrılabilir.
ThreadPool.QueueUserWorkItem(ThreadProc, “Thread 1”);
ThreadPool.QueueUserWorkItem(ThreadProc, “Thread 2”);
ThreadPool.QueueUserWorkItem(ThreadProc, “Thread 3”);
ThreadPool.QueueUserWorkItem(ThreadProc, “Thread 4”);
Thread havuzunda varsayılan olarak, işlemci
başına
maksimum
250
çalışan
thread
bulunabilir.
Background & Foreground Threadler
Ana uygulama her zaman için önplandaki
(foreground) thread’dir. Ön plandaki thread
aktif olduğu sürece, uygulama çalışmaya devam
eder.
Arkaplandaki threadler, ön plandaki threadler
çalışmalarını
bitirince
çalışmalarını
sonlandırırlar.
IsBackground : Bu özellik sayesinde thread’in
arka planda çalışan bir thread olup olmadığı
kontrol edilebilir.
class Program
{
static void Main(string[] args)
{ ThreadPool.QueueUserWorkItem(ThreadProc,"Thread 1");
ThreadPool.QueueUserWorkItem(ThreadProc, "Thread 2");
ThreadProc("Thread 3");
ThreadPool.QueueUserWorkItem(ThreadProc, "Thread 4");
Console.WriteLine("Ana thread çalışmakta ardından uyumakta");
Thread.Sleep(5000); Console.WriteLine("Ana threadten çıkılıyor");
}
static void ThreadProc(object stateinfo)
{ string state = (string)stateinfo;
if (Thread.CurrentThread.IsBackground == true)
Console.WriteLine("Arkaplan threadinden merhaba"+state);
else Console.WriteLine("Önplan threadinden merhaba"+state);
}
}
Thread’lerin Yönetimi
Bir metodu arkaplan threadi olarak çalıştırmak
her zaman yeterli olmayabilir. Threadleri
manual olarak başlatmak, durdurmak, yeniden
başlatmak ve sonlandırmak gerekebilir.
Threadler ile bu şekilde çalışmak ise kaynak
çatışmalarına (resource conflicts) neden
olabilir.
Başlatma / Durdurma
Bir thread, Thread nesnesi oluşturulduktan
sonra Thread.Start ile başlatılabilir.
Sonlandırmak için ise Thread.Abort kullanılır.
(Abort durumunda ThreadAbortException
uyarısı alınır ve bunun
yakalanması ve
ardından finally bloğu ile tüm kaynakların
serbest bırakılması gerekmektedir.)
class ThreadTest
{
static void Main( )
{
Thread t = new Thread (WriteY);
t.Start();
for (int i = 0; i < 1000; i++) Console.Write ("x");
}
static void WriteY( )
{
for (int i = 0; i < 1000; i++) Console.Write ("y");
}
}
class Program
{
static void Main(string[] args)
{
Thread DoWorkThread = new Thread(new ThreadStart(DoWork));
DoWorkThread.Start(); Thread.Sleep(5000);
DoWorkThread.Abort();
Console.WriteLine("Main threadi sonlanmakta");
Thread.Sleep(6000);
}
public static void DoWork() {
Console.WriteLine("DoWork metodu başka bir threadin içinde çalışmaktadır");
try
{ Thread.Sleep(5000); }
catch (ThreadAbortException ex) { Console.WriteLine("Thread iptal edilmiştir");}
finally
{Console.WriteLine("Kaynaklar serbest bırakılmakta"); }
Console.WriteLine("DoWork sonlandırılıyor");
}
}
Bir thread nesnesi oluştrulduktan sonra bu
nesnenin önceliği Thread.Priority özelliği
ThreadPriority numaralandırıcısı kullanılarak
düzenlenebilir.
Thread önceliği, işletim sisteminin threadi
nasıl zamanlayacağını (schedule time) kontrol
eder.
ThreadPriority 4 kategori olarak değer
almaktadır:
•
•
•
•
•
Highest
AboveNormal
Normal  Varsayılıdır.
BelowNormal
Lowest
Durumlar (Thread State)
Thread’in durumu Thread.ThreadState özelliği
yardımıyla öğrenilebilir. Threadler aşağıdaki
durumlardan herhangi biri veya birkaçında
olabilirler.
- UnStarted
- Running
- Stopped
- WaitSleepJoin
- SuspendRequested
- Suspended
- AbortRequested
- Aborted
Kaynaklara Erişimin Senkronize Edilmesi
Eğer bir uygulama herhangi bir dosyaya yazma
işlemi yapacaksa, dosyayı kilitler. Bu işlem,
diğer uygulamaların bu dosyaya erişmesinin
önüne geçer.
Diğer uygulama dosyaya erişmek isterse ya
kilidin açılmasını bekleyecek ya da dosyaya
erişim istemini iptal edecektir.
Paylaşımlı kaynaklar üzerinde çalışan çok
threadli uygulamalarda da benzer durum söz
konusudur.
Bu problemlerin giderilmesi için .NET sınıf
kütüphanesi
senkronizasyon
nesneleri
oluşturmuştur.
Bu
nesneler
yardımıyla
kaynaklar, threadler arasında eş zamanlı
olarak koordine edilebilir.
Senkronizasyona gereksinim duyan kaynaklar
şu şekilde olabilir:
• Sistem kaynakları(örn:iletişim portları)
• Çoklu processler tarafından paylaşılan
kaynaklar(file handles)
• Çoklu threadler tarafından erişilen nesneler.
Monitor
• Monitor sınıfı kullanılarak kodun belirli bir
kısmı kilitlenebilir. Kilit açılıncaya kadar diğer
threadler bu kısma erişemezler.
• Bu sınıfın Monitor.Enter() ve Monitor.Exit()
metotları kullanılabileceği gibi “lock” anahtar
sözcüğü de kullanılabilir.
Reader/Writer
Bazı durumlarda kod bloğu üzerinde bir
thread değişiklik yaparken başka bir thread in
okuma yapmasına izin verilebilir.
Interlocked
Temel aritmatiksel işlemleri Thread güvenli
olarak yapabilmek için “Interlocked” sınıfı
kullanılır. Bu sınıf, atomik işlemleri aşağıdaki
metotları çağırarak gerçekleştirir.
- Increment
- Decrement
- Exchange
- CompareExchange
- Add
-Read