Geri git   Van.GEN.TR Forum | Yerel Van Forumu > Bilgisayar > Programlama > Visual Basic, Delphi, C++ Ve Diğer Diller

Cevapla
 
Konu Araçları Stil
Alt 22/06/07, 13:52   #1
LastDesiqner
Super Moderator
 
LastDesiqner - ait Kullanıcı Resmi (Avatar)
 
Üyelik tarihi: Jan 2007
Bulunduğu yer: ναη
Mesajlar: 8.132
Tecrübe Puanı: 56 LastDesiqner has a reputation beyond repute LastDesiqner has a reputation beyond repute LastDesiqner has a reputation beyond repute LastDesiqner has a reputation beyond repute LastDesiqner has a reputation beyond repute LastDesiqner has a reputation beyond repute LastDesiqner has a reputation beyond repute LastDesiqner has a reputation beyond repute LastDesiqner has a reputation beyond repute LastDesiqner has a reputation beyond repute LastDesiqner has a reputation beyond repute
Standart C# ile multithreading programlamaya giriş

Bu yazımızda size c# ile multithreading programlamaya küçük bir giriş yapacağım. Multithreading kavramı türkçeye çok kanallı programlama diye çevrilmiş; bunu da belirtmekte fayda var, en azından bu şekilde ne olduğuna ilişkin bir fikir sahibi olabilirsiniz.


Çok kanallı programlama Nedir?


Çok kanallı programlama şuan siz bu yazıyı okurken karşınızda olan şeydir. Muhtemelen bu yazıyı okurken yalnızca internet tarayıcınız çalışmıyor bilgisayarınızda; bir tarafta müzik çalıcı, bir tarafta antivirüs yazılımı, bir tarafta mesajlaşma yazılımınız çalışır vaziyette, hatta belki de bunu okurken biri ile sesli görüşme bile yapıyor olabilirsiniz.

İşte bu şekilde bir bilgisayarda aynı anda birden fazla programın çalışması işine çok kanallı çalışma diyoruz.
Çok kanallı programlamada da biz yalnızca bir program içinde aynı anda çalışan birden fazla küçük işlemleri çalıştıracağız. Burada şunu unutmamak gerekir; çok kanallı programlama demek yalnızca işletim sisteminde birden fazla uygulamanın çalışması değil aynı program içinde de birden fazla işlemin (thread) aynı anda çalışması demektir.

Programlamaya C veya Pascal gibi yapısal (modüler) dillerle başlayanlar bilirler; bir kod akış grafiği vardır, program alt rutinden(fonksiyon, prosedür) altrutine dallanır, akar ve biter. Böylesi bir mantıkla örneğin MS Word 2000 gibi bir programın çalışmasını anlamak mümkün değildir. Bu program aynı anda hem sizin yaınızı alan (scanf gibi bir işlem), hem yazdıklarınızı denetleyen ve yanlış yazıları işaretleryen, hem ara ara dosyanızı kaydeden, resim ve diğer dosyaların oynatma ve yerleştirme işlemlerini yapan, hem de yazıcıdan çıktı üreten bir yazılımdır. Siz bunu bir noktadan başlayıp adım adım işleleri yapan komple bir yapı olarak kurgulamaya çalıştığınızda işin içinden çıkamazsınız. İşte çok kanallı programlama ile her bir alt işlemi ayrı bir kanalda (yolda) çalışacak şekilde programlayıp aynı anda hepsinin çalışmasını sağlamak multithreadi'tir.
Şimdi c# dili ile bu işlemin nasıl yapılacağına değinelim.

Önce bir thread'in aslında bizim kullandığımız fonksiyonlardan pek de farklı olmadığını (en azından bu mantıkla kullanabileceğimizi belirtmek gerek, yani ortada tümüyle yeniden öğrenmeyi gerektirecek bir şey yok.
Şimdi iki tane koşucumuz olsun ve biz bu koşucuları yarıştıralım. Bir buton ile yarışı başlatalım ve butonun işlevine de iki koşucunun yarışa başması için gerekli başlangıç kodunu yazalım ve sonucu görelim.


Alıntı:
public void kosucu1()
{
for(int i=0;i<100;i++)
{
System.Threading.Thread.Sleep(1);
Application.DoEvents();//bunlar döngüde herşeyin yolunda gitmesi için kullanılıyor
}
label1.Text = "Ben birinci kosucuyum";
}

public void kosucu2()
{
for(int i=0;i<100;i++)
{
System.Threading.Thread.Sleep(1);
Application.DoEvents();//bunlar döngüde herşeyin yolunda gitmesi için kullanılıyor
}
label2.Text = "Ben ikinci koşucuyum";
}


private void button1_Click(object sender, System.EventArgs e)
{
kosucu1();
kosucu2();

}
Kodumuzu bu şekilde yazıp çalıştırdığımızda önce label1'de "Ben birinci koşucuyum", biraz sonra da label2'de "Ben ikinci koşucuyum" yazdığını göreceksiniz. Bunun anlamı birinci koşucumuzun yarışı kazandığıdır ancak burada bir adaletszlik söz konusu. Çünkü buton1'in kodunda önce koşucu1'in yarışını bitirmesini sağlayan kosucu1(); fonksiyonunu yazdık, bu fonksiyon icra edildi, label1'e yazı yazıldı, sonra ikincis koşucunun fonksiyonuna geçildi. Bu da her zaman koşucu1'in birinci olacağı, aslında bunu bir yarış olmadığı anlamına gelir.

Peki ya şöyle olsaydı: Biz butona bastığımızda aynı anda iki koşucu da başlasa ve hangisi daha önce hedefe varırsa o ilk önce "Vardım" diye yazsa. İşte bunun için Thread'ları kullanacağız.

Thread'larla ilgili iki temel veri tipi (sınıf, temsilci) kullanacağız; şimdi bunların hem örneklerini verelim, hem de anlatalım:


Alıntı:
System.Threading.ThreadStart t_baslat1;
System.Threading.ThreadStart t_baslat2;

System.Threading.Thread t1;
System.Threading.Thread t2;
Biri ThreadStart biri de Thread olmak üzre ikişer değişken kullandık. ThreadStart bir Thread'ın başlatılması için kullanılan bir sınıftır. Bu sınıfa eşzamanlı çalıştırmak istediğimiz fonksiyonun ismini verdiğimizde bize bir Thread oluşturmak için gerekli hazırlığı yapar. Thread sınfı ile de oluşan bu işi (thread) yönetiriz.

Buton1'e tıklandığında çalışan kodu şu şekilde değiştirelim:


Alıntı:
private void button1_Click(object sender, System.EventArgs e)
{
t_baslat1 = new System.Threading.ThreadStart(kosucu1);
t_baslat2 = new System.Threading.ThreadStart(kosucu2);

t1 = new System.Threading.Thread(t_baslat1);
t2 = new System.Threading.Thread(t_baslat2);

t1.Start();
t2.Start();
}
Gördüğünüz gibi önce ThreadStart ile fonksiyonları aldık, sonra da bu Thread başlatıcıları Thread sınıflarına verdik. Bütün hazırlıklar bittiğinde ise


Alıntı:
t1.Start()
gibi bir fonksiyon ile bu işi başlattık. Kodu bu şekilde derleyip çalıştırdığımızda hoş bir sonuç ile karşılaşacağız. For döngülerine verdiğimiz değerler aynı olduğu için bu iki fonksiyonun icra süreleri aynıdır, yaklaşık olarak aynı anda başladıkları için de aynı anda label1'de "Ben birinci koşucuyum", label2'de de "Ben ikinci koşucuyum" yazısı çıkacaktır.

Şimdi işler kızıştı Şimdi koşucu1 ve koşucu2 fonksiyonlarına gidip döndülerin değelerinde küçük değişiklikler yapın. Örneğin koşucu1'in döngü sayısını 100'den 300'e çıkarın; bu kez koşucu 2'nin çok daha erken hedefe varacağını, koşucu1'in ise ondan 200 milisaniye sonra geleceğini görün.

Tamam ayrı işlemleri ayrı kanallardan oluşturduk. Peki bunların dışında bir işlemi yönetmek için gerekli olan başka bir araç yok mu? Tabii ki var. Bir Threadin başlatılması, durdurulması, duraklatılması ve durduğu yerden devam etmesi gerekir çoğu zaman işte bu işlemler için gerekli fonksiyonlar şöyle;


Alıntı:
t1.Suspend();
Bir işi tıpkı winamp programında çalan şarkıyı "pause" ettiğiniz gibi durdurur.


Alıntı:
t1.Resume();
Çalan şarkıyı kaldığı yerden devam ettirir Suspend metodu ile durdurulmuş işi kaldığı yerden devam ettirir.

Alıntı:
t1.Abort();
Devam eden işlemi sonlandırır, bitirir. Abort ile sonlanmış işlem geri döndürülmez.


Alıntı:
t1.ThreadState
Bununla Threadin durumunu öğreniriz

Alıntı:
t1.IsAlive
Bununla threadin hala hayatta olup olmadığını öğreniriz.


Alıntı:
t1.Priority
Bu değer hem okunabilir, hem de yazılabilirdir. Bununla threadimizin öncelik değerini öğrenir veya değiştirebiliriz (belirleyebiliriz).

Bir oyun yazdınız; oyunda kullanıcının hareket ettirdiği bir adam ve bilgisayarın yönettiği, adamınızı yakalamaya çalışan böcekler var. Böyle bir oyunu yapısal bir programlama dili ile yazarken ya adamınızın ve böceklerin hızları aynı olacak ya da böcekler adamınızın hareket etme döngüsü içinde bir hareket edecekler, bir etmeyecekler ve hızları adamın hızının yarısı olacak. Her şeyden önce böyle bir kodlama korkunç karışık ve verimsiz olur. Oysa çok kanallı programlama ile her bir robotu (adam ve böcekler) ayrı ayrı programlar farklı kanallardan çalıştırırsanız hem kodlamanız kolay hem de programınız daha etkili olur.

Bu basit örnek sadece anlaşılması içindi oysa çok kanallı programlamanın kullanım yeri bu tür alt seviye işlemlerle sınırlı değildir. Bugün kullandığınız profesyonel programların hemen hepsi multithreading destekli yazılmıştır.

Ancak çok kanallı programlamanın da bir zayıf noktası vardır.

Malum şu an kullandığımız bilgisayarların çoğu tek işlemci kullanıyor ve bir işlemci aslında aynı anda sadece bir işlem yapabilir. Aynı anda çalışıyormuş gibi çalışan programlar çok küçük parçalara bölünür, her bir zaman biriminde ilk programın bir parçası, sonra ikinci programın bir parçası ... son programın bir parçası ve sonra tekrar ilk program en son çalıştırılan parçadan itibaren diğer arçası çalıştırılır. Çok hızlı yapılan bu işlem bütün programların aynı anda çalışıyormuş gibi hissedilmesine sağlar. Burada önemli olan işlemcinin bu görev parçacıkları arasındaki geçişidir. Az sayıda program varken bu pek sorun olmaz ancak program sayısı çoğaldıkça görevler arası geçiş çok zaman almaya başlar ve işlemci sırf görev geçişleri yüzünden kafasını kaldıracak zaman bulamaz. Çok kanallı programlama verimli bir uygulama iken böylesi bir durumda verim düşer. İşlemcinin bu şekilde kalmasına "açlıktan ölme" (starvation) denir. Bu sebeple çok kanallı programlama uygulanırken boş yere threadlar çoğaltılmamalı işlemcinin ve belleğin durumu göz önünde bulundurulmalıdır.

Programın tam halini (daha doğrusu basit bir örneği) sisteme yüklemek istedim ama sanıyorum bir sorun var; o yüzden buraya kodları yapıştırıyorum:


Alıntı:
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

namespace dersicin
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.Button button1;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label2;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;

public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();

//
// TODO: Add any constructor code after InitializeComponent call
//
}

/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
this.label1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// button1
//
this.button1.Location = new System.Drawing.Point(136, 24);
this.button1.Name = "button1";
this.button1.TabIndex = 0;
this.button1.Text = "Başla";
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// label1
//
this.label1.Location = new System.Drawing.Point(40, 88);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(128, 23);
this.label1.TabIndex = 1;
this.label1.Text = "label1";
//
// label2
//
this.label2.Location = new System.Drawing.Point(216, 88);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(144, 23);
this.label2.TabIndex = 2;
this.label2.Text = "label2";
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(376, 149);
this.Controls.Add(this.label2);
this.Controls.Add(this.label1);
this.Controls.Add(this.button1);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);

}
#endregion

/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}

public void kosucu1()
{
for(int i=0;i<100;i++)
{
System.Threading.Thread.Sleep(1); //1 milisaniye bekle
Application.DoEvents(); //bunlar döngüde herşeyin yolunda gitmesi için kullanılıyor
}
label1.Text = "Ben birinci kosucuyum";
}

public void kosucu2()
{
for(int i=0;i<100;i++)
{
System.Threading.Thread.Sleep(1); //1 milisaniye bekle
Application.DoEvents();//bunlar döngüde herşeyin yolunda gitmesi için kullanılıyor
}
label2.Text = "Ben ikinci koşucuyum";
}

System.Threading.ThreadStart t_baslat1; //thread başlatıcı
System.Threading.ThreadStart t_baslat2;

System.Threading.Thread t1; //thread yönetici
System.Threading.Thread t2;


private void button1_Click(object sender, System.EventArgs e)
{
t_baslat1 = new System.Threading.ThreadStart(kosucu1);
t_baslat2 = new System.Threading.ThreadStart(kosucu2);

t1 = new System.Threading.Thread(t_baslat1);
t2 = new System.Threading.Thread(t_baslat2);

t1.Start();
t2.Start();

}
}
}
Alıntıdır
__________________
[Bu Adresi (link) Görme Yetkiniz Yok BEDAVA'ya Üye Ol Sitemizden Faydalan....]
[Bu Adresi (link) Görme Yetkiniz Yok BEDAVA'ya Üye Ol Sitemizden Faydalan....]


[Bu Adresi (link) Görme Yetkiniz Yok BEDAVA'ya Üye Ol Sitemizden Faydalan....]
LastDesiqner isimli Üye şimdilik offline konumundadır   Alıntı ile Cevapla
Konu Sayısı: 488
Takımınız:
Alt 23/06/07, 18:52   #2
gokhanaygun
Tuğgeneral
 
gokhanaygun - ait Kullanıcı Resmi (Avatar)
 
Üyelik tarihi: Apr 2007
Bulunduğu yer: VAN
Yaş: 36
Mesajlar: 925
Tecrübe Puanı: 26 gokhanaygun is a splendid one to behold gokhanaygun is a splendid one to behold gokhanaygun is a splendid one to behold gokhanaygun is a splendid one to behold gokhanaygun is a splendid one to behold gokhanaygun is a splendid one to behold gokhanaygun is a splendid one to behold
Standart

C# ile multithreading programlamaya giriş Öncelikle güzel bi konu ona sölemek lazım ..multithreading..yanı basitçe aynı anda birden fazla işlem yapma..
tabı bu c# olabileceği gibi diğer dillerde olabiilir... şimdi c# hakkında bi kaç not ekleyim ben 2000 senesinde c++ dan sonra c# yazılmış ve oldukça iddaali bir dildir. ve .net teknolojisinin ise resmi dili sayılmaktadır.Ki şuanda da microsoft hemen hemen tüm cabası .net üzerindedir. Şimdi gelelim kodlarını nasıl çalıştıcağı hakkında bi kaç şey diyim ben. öncelikle frameworks yükleyin sonra ise visual c# yüklemeniz lazım nesne eklemek için .. kolay gelsin ..
gokhanaygun isimli Üye şimdilik offline konumundadır   Alıntı ile Cevapla
Konu Sayısı: 187
Alt 31/07/08, 15:32   #3
Neutralizer
Yasaklı kullanıcı
 
Neutralizer - ait Kullanıcı Resmi (Avatar)
 
Üyelik tarihi: Jan 2008
Bulunduğu yer: İstediğin yerden
Mesajlar: 1.890
Tecrübe Puanı: 0 Neutralizer has a reputation beyond repute Neutralizer has a reputation beyond repute Neutralizer has a reputation beyond repute Neutralizer has a reputation beyond repute Neutralizer has a reputation beyond repute Neutralizer has a reputation beyond repute Neutralizer has a reputation beyond repute Neutralizer has a reputation beyond repute Neutralizer has a reputation beyond repute Neutralizer has a reputation beyond repute Neutralizer has a reputation beyond repute
Standart

paylaşım için tşkrlr
Neutralizer isimli Üye şimdilik offline konumundadır   Alıntı ile Cevapla
Konu Sayısı: 317
Takımınız:
Cevapla


Konuyu Toplam 1 Üye okuyor. (0 Kayıtlı üye ve 1 Misafir)
 
Konu Araçları
Stil

Yetkileriniz
Yeni Mesaj yazma yetkiniz Aktif değil dir.
Mesajlara Cevap verme yetkiniz aktif değil dir.
Eklenti ekleme yetkiniz Aktif değil dir.
Kendi Mesajınızı değiştirme yetkiniz Aktif değildir dir.

BB code is Açık
Smileler Açık
[IMG] Kodları Açık
HTML-KodlarıKapalı
Gitmek istediğiniz klasörü seçiniz


Bütün Zaman Ayarları WEZ +3 olarak düzenlenmiştir. Şu Anki Saat: 19:46 .


Powered by vBulletin
Copyright © 2000-2007 Jelsoft Enterprises Limited.
Sitemap
6, 5, 3, 7, 8, 9, 10, 11, 12, 13, 14, 15, 113, 16, 17, 18, 19, 81, 20, 27, 22, 23, 24, 25, 26, 48, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 43, 136, 40, 58, 45, 42, 44, 46, 47, 53, 54, 55, 56, 57, 59, 60, 70, 61, 62, 63, 64, 65, 66, 68, 69, 71, 72, 74, 75, 76, 77, 78, 79, 80, 82, 83, 96, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 98, 97, 100, 101, 102, 103, 106, 104, 105, 112, 109, 108, 107, 110, 111, 114, 115, 118, 116, 117, 119, 148, 154, 124, 165, 122, 120, 123, 121, 150, 153, 125, 128, 129, 131, 132, 133, 134, 135, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 151, 149, 202, 175, 164, 152, 167, 155, 156, 157, 158, 159, 160, 161, 162, 163, 195, 169, 166, 168, 170, 171, 172, 199, 174, 173, 196, 200, 176, 177, 180, 178, 179, 182, 189, 187, 184, 186, 191, 192, 193, 194, 197, 198, 201, 203, 229, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 236, 231, 232, 233, 234, 235, 237, 240, 239, 241, 243, 242, 244,