Thread.terminate yapınca access violation hatası!!!
Forum kuralları
Forum kurallarını okuyup, uyunuz!
Forum kurallarını okuyup, uyunuz!
- huseyinkucuk
- Üye
- Mesajlar: 142
- Kayıt: 29 Nis 2005 10:03
- Konum: İstanbul
- İletişim:
Thread.terminate yapınca access violation hatası!!!
("thread.terminate yapınca access violation hatası" başlığıyla ilgili soru en alttadır... Lütfen aşağıya bakın... Şimdiden teşekkür ederim...)
Arkadaşlar, merhaba...
Aynı kaynakları kullanan threadların birbirlerinin sırasını beklemek için sanırım 'critical section' kullanmam gerekiyomuş... Forumda aradım, bişey bulamadım... Google'la da aradım ama ordan da pek bişey bulamadım... 'Critical Section' nedir? Nasıl kullanılır? Bir örnekle kısaca anlatabilecek var mı acaba? Yardımlarınızı bekliyorum... Şimdiden teşekkür ederim, kolay gelsin...
Arkadaşlar, merhaba...
Aynı kaynakları kullanan threadların birbirlerinin sırasını beklemek için sanırım 'critical section' kullanmam gerekiyomuş... Forumda aradım, bişey bulamadım... Google'la da aradım ama ordan da pek bişey bulamadım... 'Critical Section' nedir? Nasıl kullanılır? Bir örnekle kısaca anlatabilecek var mı acaba? Yardımlarınızı bekliyorum... Şimdiden teşekkür ederim, kolay gelsin...
En son huseyinkucuk tarafından 30 May 2006 07:57 tarihinde düzenlendi, toplamda 5 kere düzenlendi.
29.04.2005 tarihi itibariyle Delphi öğrenmeye başlayan yeni bir kullanıcı sayılabilirim.
Delphi Help dosyasında Critical Section bölümünde örnekli bir açıklama mevcut.
Aynı zamanda multi-read exclusive-write synchronizer başlığına da göz atmanı öneririm.
Critical section ve mutex'lerin amacı senin de tahmin edebileceğin gibi, bir thread, diğer thread'ler ile veri paylaştığı, okuduğu-yazdığı alana, yazmak isterse, yazma işleminin aynı anda sadece 1 thread ile sınırlı olmasını sağlamaktır.
Mutex'in critical section'dan farkı şudur. Mutex kullandığında bütün thread'ler aynı anda paylaşımlı bölgeyi okuyabilir ancak sadece bir tanesi yazabilir.
Critical section'da ise bir thread'in işi bitene kadar diğer threadler durdurulur.
Sıkça yazma işlemi gerekmeyen yerlerde mutex kullanmak genel performansı arttıracaktır. Mutex kullanılması tavsiye edilir.
Aynı zamanda multi-read exclusive-write synchronizer başlığına da göz atmanı öneririm.
Critical section ve mutex'lerin amacı senin de tahmin edebileceğin gibi, bir thread, diğer thread'ler ile veri paylaştığı, okuduğu-yazdığı alana, yazmak isterse, yazma işleminin aynı anda sadece 1 thread ile sınırlı olmasını sağlamaktır.
Mutex'in critical section'dan farkı şudur. Mutex kullandığında bütün thread'ler aynı anda paylaşımlı bölgeyi okuyabilir ancak sadece bir tanesi yazabilir.
Critical section'da ise bir thread'in işi bitene kadar diğer threadler durdurulur.
Sıkça yazma işlemi gerekmeyen yerlerde mutex kullanmak genel performansı arttıracaktır. Mutex kullanılması tavsiye edilir.
- huseyinkucuk
- Üye
- Mesajlar: 142
- Kayıt: 29 Nis 2005 10:03
- Konum: İstanbul
- İletişim:
-
- Üye
- Mesajlar: 163
- Kayıt: 06 Nis 2006 12:22
Sayın huseyinkucuk,huseyinkucuk yazdı:Teşekkür ederim... Sanırım çözdüm olayı... CriticalSectionNesnesi.acquire işlemler, işlemler... CriticalSectionNesnesi.release; böyle bişeyler... Çok teşekkürler... Kolay gelsin...
Bu kanal işleri zamanında bana kafayı yedirmek üzereydi. Bu işleme kanal senkronizasyonu deniyor. Öncelikle eğer bir takım işlemleri kanallar ile gerçekleştirecekseniz kanalların kodlarını çok iyi planlamanız gerekiyor.
Aksi takdirde bir takım sorunlar olduğunda, kanalların birbiriyle eş zamanlı olarak çalışmasından dolayı hataları gidermeniz çok zor olabilir.
Benim durumumda, kanallaırn hepsi sonunda suspended konumuna geçiyordu ve bir türlü nedenini bulamıyordum. Bunun üzerine adım adım kodlara OutputDebugString fonksiyonuyla mesajlar çıkarttırıp, uygulamayı memproof ile açarak sorunu çözebilmiştim. Hala bu uygulama ara sıra kendi kendini kapatıyor.

Başarılar
- huseyinkucuk
- Üye
- Mesajlar: 142
- Kayıt: 29 Nis 2005 10:03
- Konum: İstanbul
- İletişim:
ya hocam sorma ya, kafayı yicem... Herşeylerini planlı programlı yaptım bu threadların, herşeylerini lokal değişken yaptım birbirlerinin işlerine karışmasınlar diye. Arada bi yine hata veriyo, yine hata veriyo...
Formda düğmeye basınca rasgele biyerlerden küçük küçük tanklar çıkıp rasgele biyerlere doğru gidiyolar... Başta herşey çok güzeldi, hepsi kendi yolunda gidiyo ama birbirlerini farketmiyolardı, yani birbirlerinin içinden geçiyolardı. Ben dedim yaw bunlar çarpışınca yok olsun (ilk önce geri dönsünler diye düşünmüştüm ama sonra yokolsun dedim, demez olaydım, geri dönselerdi hiç bi problemle uğraşıyo olmıcaktım şimdi
free edince çıkıyo sanırım problemler) Çarpışıyolar falan, bi kaç (bazen daha çok) çarpışmadan sonra zırt pırt access violation hatası verip duruyo... Ama program normal çalışmaya devam ediyo, sadece hatayı verip duruyo. Aslında try except ile falan hatanın görünmemesini sağlarım ama kendime yediremem bunu
Bana yardım edebilecek yok mu? Critical Section'un da nasıl kullanıldığını anlamadım zaten, hiçbiyerde yazmıyo (bi şekilde kullanayım dedim ama işe yaramadı, ya yanlış kullandım ya da işe yaramıyo) Arkadaşlar, rapide yükledim projeyi, incelemek isteyen varsa buyursun, yardım ederseniz müteşekkir olurum. Herkese kolay gelsin...
http://rapidshare.de/files/21371916/Thr ... 2.rar.html
Formda düğmeye basınca rasgele biyerlerden küçük küçük tanklar çıkıp rasgele biyerlere doğru gidiyolar... Başta herşey çok güzeldi, hepsi kendi yolunda gidiyo ama birbirlerini farketmiyolardı, yani birbirlerinin içinden geçiyolardı. Ben dedim yaw bunlar çarpışınca yok olsun (ilk önce geri dönsünler diye düşünmüştüm ama sonra yokolsun dedim, demez olaydım, geri dönselerdi hiç bi problemle uğraşıyo olmıcaktım şimdi


http://rapidshare.de/files/21371916/Thr ... 2.rar.html
29.04.2005 tarihi itibariyle Delphi öğrenmeye başlayan yeni bir kullanıcı sayılabilirim.
-
- Üye
- Mesajlar: 163
- Kayıt: 06 Nis 2006 12:22
Valla sizin açınızdan üzüldüm.huseyinkucuk yazdı:ya hocam sorma ya, kafayı yicem... Herşeylerini planlı programlı yaptım bu threadların, herşeylerini lokal değişken yaptım birbirlerinin işlerine karışmasınlar diye. Arada bi yine hata veriyo, yine hata veriyo...

Bu konuda size herhangi birinin yardımcı olabileceğini sanmıyorum. Çünkü uygulamanın mantığını ancak siz bilebilirsiniz. Kanal senkronizasyonunun mantığı belirli verilere kanalların sırayla ulaşmasını sağlamak. Kiritik Bölümlerin standart bir kullanımı maalesef ki bulunmuyor. Dolayısıyla, size kimse somut bir örnek veremez. Bence Memproof ya da Delphi IDE'nin Debug panelinden yararlanıp, kanal kodu (ve ana formun kodları) içerisinde erişim ihlallerinin vs.'nin çıktığından şüphelendiğiniz yerlerin (yani kod satırlarının) hemen öncesine Outputdebugstring('xx'inci satıra geldi') vs. gibi mesajlar çıkarttırıp, erişim ihlallerinin hangi satırlar sonrasında meydana geldiğini tespit etmeye çalışmalısınız.huseyinkucuk yazdı:Critical Section'un da nasıl kullanıldığını anlamadım zaten, hiçbiyerde yazmıyo (bi şekilde kullanayım dedim ama işe yaramadı, ya yanlış kullandım ya da işe yaramıyo) Arkadaşlar, rapide yükledim projeyi, incelemek isteyen varsa buyursun, yardım ederseniz müteşekkir olurum. Herkese kolay gelsin...
Başka bir fikir de, Jedi bileşen paketinin JVManagedThread bileşenlerini kullanmak. En azından bu hazır bileşenler sayesinde kanalları ana form içerisinde oluşturabilir ve tanklarınızı yönetebilirsiniz. Ancak belki benim kişisel beceriksizliğimden kaynaklanıyor olabilir, tam olarak bilmiyorum. Fakat ben kullandığımda bu JVManagedThread bileşenleri korkunç bellek sızıntısına neden oluyordu.

Kanalları önce JVManagedThread bileşenleri ile kullandım ve daha sonra bunu normal unit şeklindeki kanallara taşıdım. Şu anda çok fazla sorun yok. Ancak ara sıra kendi kendine uygulama kapanıyor. Bu profesyonel bir uygulama olmadığından dolayı çok fazla da uğraşmıyorum işin açıkçası. Çünkü dediğim gibi kanal sorunu gerçekten insana kafayı sıyırttırıyor.

Saygılar ve Başarılar.
http://www.marcocantu.com/code/md5/THSY ... RISECT.PAShuseyinkucuk yazdı: Critical Section'un da nasıl kullanıldığını anlamadım zaten, hiçbiyerde yazmıyo (bi şekilde kullanayım dedim ama işe yaramadı, ya yanlış kullandım ya da işe yaramıyo)
Kod: Tümünü seç
unit TCriSect;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, SyncObjs;
type
TListThread = class (TThread)
private
Str: String;
protected
procedure AddToList;
procedure Execute; override;
public
LBox: TListBox;
end;
TForm5 = class(TForm)
BtnStart: TButton;
ListBox1: TListBox;
ListBox2: TListBox;
procedure BtnStartClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
Th1, Th2: TListThread;
public
{ Public declarations }
end;
var
Form5: TForm5;
Letters: string = 'AAAAAAAAAAAAAAAAAAAA';
Critical1: TCriticalSection;
implementation
{$R *.DFM}
procedure TListThread.AddToList;
begin
if Assigned (LBox) then
LBox.Items.Add (Str);
end;
procedure TListThread.Execute;
var
I, J, K: Integer;
begin
for I := 0 to 50 do
begin
Critical1.Enter;
for J := 1 to 20 do
for K := 1 to 2601 do // useless repetition...
if Letters [J] < 'Z' then
Letters [J] := Succ (Letters [J])
else
Letters [J] := 'A';
Str := Letters;
Critical1.Leave;
Synchronize (AddToList);
end;
end;
procedure TForm5.BtnStartClick(Sender: TObject);
begin
ListBox1.Clear;
ListBox2.Clear;
Th1 := TListThread.Create (True);
Th2 := TListThread.Create (True);
Th1.FreeOnTerminate := True;
Th2.FreeOnTerminate := True;
Th1.LBox := Listbox1;
Th2.LBox := Listbox2;
Th1.Resume;
Th2.Resume;
end;
procedure TForm5.FormCreate(Sender: TObject);
begin
Critical1 := TCriticalSection.Create;
end;
procedure TForm5.FormDestroy(Sender: TObject);
begin
Critical1.Free;
end;
end
- huseyinkucuk
- Üye
- Mesajlar: 142
- Kayıt: 29 Nis 2005 10:03
- Konum: İstanbul
- İletişim:
Arkadaşlar, teşekkür ederim... Eve gidince denicem bunu... Marco Cantu'nun kitabı da var ama orda da thread'ler ile ilgili pek fazla bilgi bulamadım... Demek ki sitesinde varmış... Teşekkür ederim, hepinize kolay gelsin... Yeni sorularımla başınızı ağrıtabilirim, ilgilendiğiniz için teşekkürler...
29.04.2005 tarihi itibariyle Delphi öğrenmeye başlayan yeni bir kullanıcı sayılabilirim.
Selam,
Senin sorunun Critical Section'la ilgili değil sanırım. Kodda bir iki değişiklik yaptım ve RapidShare tekrar attım. Uzun bir süre beklememe ve bir sürü çarpışma olmasına rağmen hata vermedi. Linki aşağıda.
http://rapidshare.de/files/21416677/Tank.rar.html
Anladığım kadarıyla asıl sorun şurada. Tank listesini her seferinde dinamik olarak çıkarıyorsun, ama bu liste sana her zaman gerçek listeyi vermiyor. Kimi zaman listedeki tanklardan birisi terminated ve dolayısıyla silinmiş olabiliyor. Pek doğru olmamasına rağmen farklı bir şekilde bir çözüm ürettim. Ana forma bir tane TList yerleştirdim ve eklenen bütün tankları bu listeye attım. Daha sonra da Thread içinde tank listesini dinamik almadım, onun yerinde ana formdaki listeyi kullandım. Ana liste daima son eleman listesini tuttuğu için problem yaratmayacaktır (Eğer bu sistemi birebir kullanacaksan, burada range kontrolü yaptırman iyi olur) Eğer Critical Section kullanılacaksa, bu listeye erişirken kullanılmalı. Ama sen bu listeye erişen kodları syncronize içine altığın için, burada da problem olacağını sanmıyorum. Zaten kodun tamamı sync içinde olduğu için ve aynı zamanda kodlarında bazı optimizasyonlar eksik olduğu için tanklar hareket ederken çok fazla titreme yapıyor.
Ana listenin sürekli güncel olması gerektiği için, herhangi bir thread silineceği zaman, aynı zamanda listeden de silinmeli. Bu yüzden FreeOnTerminate şeklinde çalışması sorun yaratır. Bunu da kendi tanımladığım bir mesajı ana forma göndererek hallettim (WM_ThreadEnd).
Program kapanırken bütün threadlerin sona erdirilmesini de bekletiyor. Bu yüzden program kapanırken kısa bir süre bekliyor.
Ayrıca Tank sınıfında da bellek kaybı oluşuyor. Eğer programın sendeki sürümünü çalıştırırken Task Manager'i açacak olursan, kullanılan bellek miktarının sürekli arttığını ve nesneler yok edilmesine rağmen alınan belleğin geri verilmediğini göreceksin. Ben buna da bir şeyler yaptım, asıl sorun class'ın constructor'ında create ettiğin Image nesnelerini, destory ederken silmiyor olman. Ayrıca constructor'ınla ilgili de warning veriyor. Ben senin yerinde olsam, bu warningi engelleyecek şekilde kodu değiştirirdim.
Son olarak ben senin yerinde olsam kesinlikle böyle hazırlamazdım. Tank resimlerin standart. Bu yüzden bir class hazırla, bu class tank yeri ve yönünü tutsun. Bu yöne göre de bir image listesinden hangi resmi kullanacağını bilsin. Yani bütün programda toplam 8 tane resim olacak. Class gerektiği zaman canvasa bu resimleri çizdirsin. Böylece çok daha az bellek kullanmış olursun. Çünkü 20 tane tank yarattığın zaman bellek kullanımı ciddi oranda yükseliyor.
Ayrıca threadlerle ilgili can sıkıcı bir durum daha var. Her ne kadar MS yapsa bile, dokumanlarda 20'den fazla thread kullanımını pek tavsiye etmiyor. Bunun iki sebebi olabilir, bir performansın fazla düşmesi, iki her threadin aksini belirtmediğin sürece en az 1 MB yer tutması. Henüz sadece başlangıç aşamasında bu kadar çok thread kullanman, projenin devamı için sakat bir durum.
Eğer oyun yazmayı düşünüyorsan, işin bu kısmını threadle yapmamalısın zaten. Çünkü thread, aynı anda iki farklı işlem için kullanılır. Oysa senin yapmak istediğinde, o an ekranda x tane tank göstermek. Ayrıca oyundaki animasyonlar time based olacağı için, zaten threadleri durdurman gerekecek. Bu yüzden aslında benim yukarıda yazdığım gibi class hazırlaman ve bunları adam gibi bir listede tutman daha iyi olacaktır. Bu listede yapacağın buble sort algoritması ile de çarpışmaları tespit edip, listede eleme yapmalı ve sonra da listeyi ekrana basmalısın. Time-based bir sistemde thread kullanmanın bir anlamı yok. Oyunlarda da zaten bu kısımlar thread ile yapılmıyor. Thread ile daha çok yapay zeka kısmı yapılıyor. Normalde bütün animasyonlar yapılır (yani poligonların yeni pozisyonları bir şekilde belirlenir - bir şekilde dememin özel bir sebebi var, çünkü bunun 3 farklı yöntemi var) sonra da poligon bufferının ekrana basılacağı komutu verilir, poligonlar buffera yazılır (Buffer burada ekran kartı da olabilir, sistem belleği de, tamamen kullanılan enginein yapısına bağlı). Son olarak bütün poligonların buffera yazıldığı komutu gönderilir. Engine bu komutu aldıktan sonra gösterilecek olan resmi oluşturur ve bunu ekrana basar. Dikkat edersen bu sistemde thread falan yok. Dümdüz bir fonksiyon var aslında. Hatta C++'daki template kütüphanes (STL) bu işlemler için yavaş kaldığından dolayı oyun programcılığında STL kullanılmaz, onun yerine hand optimized listeler kullanılır.
Ayrıca zamanlama için standart timerı da kullanamazsın, high precision bir timera ihtiyacın var. Bunu da Jedi kütüphanesinde bulabilirsin (Yanlış hatırlıyor olabilirim, ama en kötü nette arattırırsın). Gerçi GDI fonksiyonları ile oyunu pek fazla ilerletemezsin ama başlangıçta OpenGL ya da DirectX kullanmaktan daha kolay olacağı kesin.
Kolay gelsin,
Bahadır Alkaç
Senin sorunun Critical Section'la ilgili değil sanırım. Kodda bir iki değişiklik yaptım ve RapidShare tekrar attım. Uzun bir süre beklememe ve bir sürü çarpışma olmasına rağmen hata vermedi. Linki aşağıda.
http://rapidshare.de/files/21416677/Tank.rar.html
Anladığım kadarıyla asıl sorun şurada. Tank listesini her seferinde dinamik olarak çıkarıyorsun, ama bu liste sana her zaman gerçek listeyi vermiyor. Kimi zaman listedeki tanklardan birisi terminated ve dolayısıyla silinmiş olabiliyor. Pek doğru olmamasına rağmen farklı bir şekilde bir çözüm ürettim. Ana forma bir tane TList yerleştirdim ve eklenen bütün tankları bu listeye attım. Daha sonra da Thread içinde tank listesini dinamik almadım, onun yerinde ana formdaki listeyi kullandım. Ana liste daima son eleman listesini tuttuğu için problem yaratmayacaktır (Eğer bu sistemi birebir kullanacaksan, burada range kontrolü yaptırman iyi olur) Eğer Critical Section kullanılacaksa, bu listeye erişirken kullanılmalı. Ama sen bu listeye erişen kodları syncronize içine altığın için, burada da problem olacağını sanmıyorum. Zaten kodun tamamı sync içinde olduğu için ve aynı zamanda kodlarında bazı optimizasyonlar eksik olduğu için tanklar hareket ederken çok fazla titreme yapıyor.
Ana listenin sürekli güncel olması gerektiği için, herhangi bir thread silineceği zaman, aynı zamanda listeden de silinmeli. Bu yüzden FreeOnTerminate şeklinde çalışması sorun yaratır. Bunu da kendi tanımladığım bir mesajı ana forma göndererek hallettim (WM_ThreadEnd).
Program kapanırken bütün threadlerin sona erdirilmesini de bekletiyor. Bu yüzden program kapanırken kısa bir süre bekliyor.
Ayrıca Tank sınıfında da bellek kaybı oluşuyor. Eğer programın sendeki sürümünü çalıştırırken Task Manager'i açacak olursan, kullanılan bellek miktarının sürekli arttığını ve nesneler yok edilmesine rağmen alınan belleğin geri verilmediğini göreceksin. Ben buna da bir şeyler yaptım, asıl sorun class'ın constructor'ında create ettiğin Image nesnelerini, destory ederken silmiyor olman. Ayrıca constructor'ınla ilgili de warning veriyor. Ben senin yerinde olsam, bu warningi engelleyecek şekilde kodu değiştirirdim.
Son olarak ben senin yerinde olsam kesinlikle böyle hazırlamazdım. Tank resimlerin standart. Bu yüzden bir class hazırla, bu class tank yeri ve yönünü tutsun. Bu yöne göre de bir image listesinden hangi resmi kullanacağını bilsin. Yani bütün programda toplam 8 tane resim olacak. Class gerektiği zaman canvasa bu resimleri çizdirsin. Böylece çok daha az bellek kullanmış olursun. Çünkü 20 tane tank yarattığın zaman bellek kullanımı ciddi oranda yükseliyor.
Ayrıca threadlerle ilgili can sıkıcı bir durum daha var. Her ne kadar MS yapsa bile, dokumanlarda 20'den fazla thread kullanımını pek tavsiye etmiyor. Bunun iki sebebi olabilir, bir performansın fazla düşmesi, iki her threadin aksini belirtmediğin sürece en az 1 MB yer tutması. Henüz sadece başlangıç aşamasında bu kadar çok thread kullanman, projenin devamı için sakat bir durum.
Eğer oyun yazmayı düşünüyorsan, işin bu kısmını threadle yapmamalısın zaten. Çünkü thread, aynı anda iki farklı işlem için kullanılır. Oysa senin yapmak istediğinde, o an ekranda x tane tank göstermek. Ayrıca oyundaki animasyonlar time based olacağı için, zaten threadleri durdurman gerekecek. Bu yüzden aslında benim yukarıda yazdığım gibi class hazırlaman ve bunları adam gibi bir listede tutman daha iyi olacaktır. Bu listede yapacağın buble sort algoritması ile de çarpışmaları tespit edip, listede eleme yapmalı ve sonra da listeyi ekrana basmalısın. Time-based bir sistemde thread kullanmanın bir anlamı yok. Oyunlarda da zaten bu kısımlar thread ile yapılmıyor. Thread ile daha çok yapay zeka kısmı yapılıyor. Normalde bütün animasyonlar yapılır (yani poligonların yeni pozisyonları bir şekilde belirlenir - bir şekilde dememin özel bir sebebi var, çünkü bunun 3 farklı yöntemi var) sonra da poligon bufferının ekrana basılacağı komutu verilir, poligonlar buffera yazılır (Buffer burada ekran kartı da olabilir, sistem belleği de, tamamen kullanılan enginein yapısına bağlı). Son olarak bütün poligonların buffera yazıldığı komutu gönderilir. Engine bu komutu aldıktan sonra gösterilecek olan resmi oluşturur ve bunu ekrana basar. Dikkat edersen bu sistemde thread falan yok. Dümdüz bir fonksiyon var aslında. Hatta C++'daki template kütüphanes (STL) bu işlemler için yavaş kaldığından dolayı oyun programcılığında STL kullanılmaz, onun yerine hand optimized listeler kullanılır.
Ayrıca zamanlama için standart timerı da kullanamazsın, high precision bir timera ihtiyacın var. Bunu da Jedi kütüphanesinde bulabilirsin (Yanlış hatırlıyor olabilirim, ama en kötü nette arattırırsın). Gerçi GDI fonksiyonları ile oyunu pek fazla ilerletemezsin ama başlangıçta OpenGL ya da DirectX kullanmaktan daha kolay olacağı kesin.
Kolay gelsin,
Bahadır Alkaç
- huseyinkucuk
- Üye
- Mesajlar: 142
- Kayıt: 29 Nis 2005 10:03
- Konum: İstanbul
- İletişim:
hocam, teşekkür ederim, harikasın. Sanırım gerçekten de çözmüşsün problemi. Kodları ve yazını tam okuyamadım, misafirim var. Daha sonra okucam. Tebrik ediyorum ve teşekkür ediyorum. Kolay gelsin... (Bundan sonra da yardımlarını bekliyorum, saol)
29.04.2005 tarihi itibariyle Delphi öğrenmeye başlayan yeni bir kullanıcı sayılabilirim.
- huseyinkucuk
- Üye
- Mesajlar: 142
- Kayıt: 29 Nis 2005 10:03
- Konum: İstanbul
- İletişim:
Bahadır hocam, teşekkür ederim, benim için o kadar uğraşmışsın, emek vermişsin... Umarım benim problemimi çözmek senin ilerlemene de yardımcı olmuştur... Hocam, aslında amacım oyun ahazırlamak falan değil (bazen aklımdan geçse de bu işi çok da iyi yapamayacağımı biliyorum (en azından şimdilik)), ben thread'leri yeni yeni öğreniyorum, bi iki şey yaptım işte; ekranın farklı yerlerinde 0dan 100 e kadar sayan sayılar falan (kitaptaki örnekler gibi bişey yani), Sonra kendi kendime dedim, yaw dedim, ben böyle hareket eden, birbirini farkeden nesneler yapamaz mıyım? dedim. Daha önceden yön tuşlarıyla hızlandırıp yavaşlattığım, formun kenarlarına çarpan bi tank yapmıştım (normal döngüyle), sonra threadla bu tankların küçüklerinden istediğim kadar yapayım da bakalım birbirlerini görebilecekler mi (yani çarpışabilecekler mi? gibi) diye yaptım. Anlayacağın tek amacım şimdilik kendi sınırlarımı görebilmekti. Yazdıklarına göre çok da ilerleyememişim
Ama umarım hepsini hallederim... Doğru diyosun, oyun yazma açısından çok da güzel bir yol seçmedim, söylediğim gibi, amacım sadece thread'leri öğrenmekti... Bu başlığı açmamdaki amacım da yaptığım uygulamanın niye hata verdiğini öğrenmekti. Hatanın sebebini anladım sanırım... Hocam çok teşekkür ederim... Kendine iyi bak... Kolay gelsin...

29.04.2005 tarihi itibariyle Delphi öğrenmeye başlayan yeni bir kullanıcı sayılabilirim.
- huseyinkucuk
- Üye
- Mesajlar: 142
- Kayıt: 29 Nis 2005 10:03
- Konum: İstanbul
- İletişim:
Arkadaşlar, başka bir başlıkla yazmam gerekebilirdi ama önceden yazdığımla az buçuk alakalı diye buraya yazma gereği duydum...
Aşağıdaki kodu yazdım. Kendi yaptığım thread sınıfı yine kendi yaptığım başka bir sınıfı kullanıyor... Thread'ı yaratıyorum, tlist içinde tutuyorum yaratılanları, yokederken de tthreadtank(list.items).terminate; gibi yokediyorum... Access violation hatası veriyor, sebebi ne olabilir acaba? Kodu aşağıda veriyorum...
Aşağıdaki kodu yazdım. Kendi yaptığım thread sınıfı yine kendi yaptığım başka bir sınıfı kullanıyor... Thread'ı yaratıyorum, tlist içinde tutuyorum yaratılanları, yokederken de tthreadtank(list.items).terminate; gibi yokediyorum... Access violation hatası veriyor, sebebi ne olabilir acaba? Kodu aşağıda veriyorum...
Kod: Tümünü seç
unit UAnaUnit;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ImgList,extctrls, StdCtrls,
UTank,UThreadTank;
type
TForm1 = class(TForm)
Image1: TImage;
Image2: TImage;
Image3: TImage;
Image4: TImage;
Image5: TImage;
Image6: TImage;
Image7: TImage;
Image8: TImage;
Button1: TButton;
Button2: TButton;
Button3: TButton;
Button4: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
TankListesi:TList;
Sayac:integer;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
TankListesi:=TList.Create;
Sayac:=0;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
Tankim:TThreadTank;
begin
Tankim:=TThreadTank.create(application.MainForm,100,100,yKuzey,1,50,50,100,100,100);
Tankim.Priority:=tpLowest;
TankListesi.Add(Tankim);
form1.Caption:=inttostr(tanklistesi.Count);
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
if tanklistesi.Count<=0 then exit;
TThreadTank(TankListesi.Items[tanklistesi.Count-1]).terminate;
TankListesi.Delete(TankListesi.Count-1);
end;
end.
Kod: Tümünü seç
unit UTank;
interface
Uses StdCtrls,extctrls,controls;
Type TYonler=(yKuzey,yGuney,yDogu,yBati);
//////////////////////////////////////////
Type TTank=Class(TImage)
private
FYon:TYonler;
FHiz:Integer;
FXKonumu:Integer;
FYKonumu:integer;
FGenisligi:integer;
FBoyu:integer;
FNumarasi:integer;
FHasar:integer;
FHasaraKarsiDayanmaGucu:integer;
FEziciGucu:integer;
FSilahGucu:integer;
FOwner:TWinControl;
FKursunSayisi:integer;
FEkrandakiKursunSayisi:integer;
FYokettigiTankSayisi:integer;
Palet:boolean;
procedure SetBoyu(const Value: integer);
procedure SetEziciGucu(const Value: integer);
procedure SetGenisligi(const Value: integer);
procedure SetHasar(const Value: integer);
procedure SetHasaraKarsiDayanmaGucu(const Value: integer);
procedure SetHiz(const Value: integer);
procedure SetNumarasi(const Value: integer);
procedure SetSilahGucu(const Value: integer);
procedure SetXKonumu(const Value: integer);
procedure SetYKonumu(const Value: integer);
procedure SetYon(const Value: TYonler);
procedure SetEkrandakiKursunSayisi(const Value: integer);
procedure SetKursunSayisi(const Value: integer);
procedure YoneGoreResimTayinEt;
protected
public
property Yon:TYonler read FYon Write SetYon;
property Hiz:integer read FHiz write SetHiz;
property XKonumu:integer read FXKonumu write SetXKonumu;
property YKonumu:integer read FYKonumu write SetYKonumu;
property Genisligi:integer read FGenisligi write SetGenisligi;
property Boyu:integer read FBoyu write SetBoyu;
property Numarasi:integer read FNumarasi write SetNumarasi;
property Hasar:integer read FHasar write SetHasar;
Property HasaraKarsidayanmaGucu:integer read FHasaraKarsiDayanmaGucu write SetHasaraKarsiDayanmaGucu;
Property EziciGucu:integer read FEziciGucu write SetEziciGucu;
property SilahGucu:integer read FSilahGucu write SetSilahGucu;
property Owner:TWinControl read FOwner;
property KursunSayisi:integer read FKursunSayisi write SetKursunSayisi;
property EkrandakiKursunSayisi:integer read FEkrandakiKursunSayisi write SetEkrandakiKursunSayisi;
constructor create(AOwner:TWinControl;X,Y:Integer;AYon:TYonler;AHiz:integer;ABoy,AGenislik:integer;AEziciGucu:integer;AHasaraKarsiDayanmaGucu:integer;ASilahGucu:integer);
procedure HareketEttir;
destructor destroy;override;
end;
////////////////////////////////////////////
implementation
uses UAnaUnit;
{ TTank }
constructor TTank.create(AOwner: TWinControl; X, Y: Integer; AYon: TYonler;
AHiz, ABoy, AGenislik, AEziciGucu, AHasaraKarsiDayanmaGucu,
ASilahGucu: integer);
begin
inherited create(AOwner);
Parent:=AOwner;
Stretch:=true;
Transparent:=true;
FOwner:=AOwner;
FXKonumu:=X;Left:=X; //şimdilik çömezim, böyle yaptım...
FYKonumu:=Y;Top:=Y; //şimdilik çömezim, böyle yaptım...
FYon:=AYon;
FHiz:=AHiz;
FBoyu:=ABoy; Height:=ABoy; //şimdilik çömezim, böyle yaptım...
FGenisligi:=AGenislik; Width:=AGenislik; //şimdilik çömezim, böyle yaptım...
FEziciGucu:=AEziciGucu;
FHasaraKarsiDayanmaGucu:=AHasaraKarsiDayanmaGucu;
FSilahGucu:=ASilahGucu;
Palet:=true;
YoneGoreResimTayinEt;
end;
destructor TTank.destroy;
begin
inherited;
end;
procedure TTank.HareketEttir;
begin
case FYon of
yKuzey: begin
YKonumu:=FYKonumu-FHiz;
if palet then
picture:=form1.Image1.Picture
else
picture:=form1.Image2.Picture;
if FYKonumu<=0 then
Yon:=yGuney;
if FYKonumu-FHiz<0 then
FYKonumu:=0;
end;
yGuney: begin
YKonumu:=FYKonumu+FHiz;
if palet then
picture:=form1.Image3.Picture
else
picture:=form1.Image4.Picture;
if FYKonumu+FBoyu>=FOwner.ClientHeight then
Yon:=yKuzey;
if FYKonumu+FBoyu+FHiz>FOwner.ClientHeight then
FYKonumu:=FOwner.ClientHeight-FBoyu;
end;
yDogu: begin
XKonumu:=XKonumu+Hiz;
if palet then
picture:=form1.Image5.Picture
else
picture:=form1.Image6.Picture;
if FXKonumu+FGenisligi>=FOwner.ClientWidth then
Yon:=yBati;
if FXKonumu+FGenisligi+FHiz>FOwner.ClientWidth then
FXKonumu:=FOwner.ClientWidth-FGenisligi;
end;
yBati: begin
XKonumu:=XKonumu-Hiz;
if palet then
picture:=form1.Image7.Picture
else
picture:=form1.Image8.Picture;
if FXKonumu<0 then
Yon:=yDogu;
if FXKonumu-FHiz<=0 then
FXKonumu:=0;
end;
end;
Palet:=not palet;
end;
procedure TTank.SetBoyu(const Value: integer);
begin
FBoyu := Value; Height:=Value; //şimdilik çömezim, böyle yaptım...
end;
procedure TTank.SetEkrandakiKursunSayisi(const Value: integer);
begin
FEkrandakiKursunSayisi := Value;
end;
procedure TTank.SetEziciGucu(const Value: integer);
begin
FEziciGucu := Value;
end;
procedure TTank.SetGenisligi(const Value: integer);
begin
FGenisligi := Value; Width:=Value; //şimdilik çömezim, böyle yaptım...
end;
procedure TTank.SetHasar(const Value: integer);
begin
FHasar := Value;
end;
procedure TTank.SetHasaraKarsiDayanmaGucu(const Value: integer);
begin
FHasaraKarsiDayanmaGucu := Value;
end;
procedure TTank.SetHiz(const Value: integer);
begin
FHiz := Value;
end;
procedure TTank.SetKursunSayisi(const Value: integer);
begin
FKursunSayisi := Value;
end;
procedure TTank.SetNumarasi(const Value: integer);
begin
FNumarasi := Value;
end;
procedure TTank.SetSilahGucu(const Value: integer);
begin
FSilahGucu := Value;
end;
procedure TTank.SetXKonumu(const Value: integer);
begin
FXKonumu := Value; Left:=Value; //şimdilik çömezim, böyle yaptım...
end;
procedure TTank.SetYKonumu(const Value: integer);
begin
FYKonumu := Value; Top:=Value; //şimdilik çömezim, böyle yaptım...
end;
procedure TTank.SetYon(const Value: TYonler);
begin
FYon := Value;
end;
procedure TTank.YoneGoreResimTayinEt;
{$j+}
const
palet:boolean=true;
begin
case FYon of
yKuzey: begin
if palet then
picture:=Form1.Image1.Picture
else
picture:=form1.Image2.Picture;
end;
yGuney: begin
if palet then
picture:=form1.Image3.Picture
else
picture:=form1.Image4.Picture;
end;
yDogu: begin
if palet then
picture:=form1.Image5.Picture
else
picture:=form1.Image6.Picture;
end;
yBati: begin
if palet then
picture:=form1.Image7.Picture
else
picture:=form1.Image8.Picture;
end;
end;
end;
end.
Kod: Tümünü seç
unit UThreadTank;
interface
uses
Classes,UTank,controls,dialogs;
type
TThreadTank = class(TThread)
private
Tank:TTank;
procedure SenkronizeCalisanProsedur;
{ Private declarations }
protected
procedure Execute; override;
public
constructor
create(AOwner:TWinControl;X,Y:Integer;AYon:TYonler;AHiz:integer;ABoy,AGenislik:integer;AEziciGucu:integer;AHasaraKarsiDayanmaGucu:integer;ASilahGucu:integer);
destructor
destroy;override;
end;
implementation
uses SysUtils,UAnaUnit;
{ Important: Methods and properties of objects in visual components can only be
used in a method called using Synchronize, for example,
Synchronize(UpdateCaption);
and UpdateCaption could look like,
procedure UThreadTank.UpdateCaption;
begin
Form1.Caption := 'Updated in a thread';
end; }
{ UThreadTank }
constructor TThreadTank.create(AOwner: TWinControl; X, Y: Integer;
AYon: TYonler; AHiz, ABoy, AGenislik, AEziciGucu,
AHasaraKarsiDayanmaGucu, ASilahGucu: integer);
begin
inherited create(false);
Tank:=TTank.create(AOwner,x,y,AYon,AHiz,ABoy,AGenislik,AEziciGucu,AHasaraKarsiDayanmaGucu,ASilahGucu);
FreeOnTerminate:=true;
end;
destructor TThreadTank.destroy;
begin
// form1.Caption:='threadtank.destroy çalıştı';
Tank.destroy;
inherited destroy;
end;
procedure TThreadTank.Execute;
begin
while (not Terminated) do
begin
Synchronize(SenkronizeCalisanProsedur);
Sleep(50);
end;
{ Place thread code here }
end;
procedure TThreadTank.SenkronizeCalisanProsedur;
begin
Tank.HareketEttir;
end;
end.
29.04.2005 tarihi itibariyle Delphi öğrenmeye başlayan yeni bir kullanıcı sayılabilirim.
- huseyinkucuk
- Üye
- Mesajlar: 142
- Kayıt: 29 Nis 2005 10:03
- Konum: İstanbul
- İletişim:
- huseyinkucuk
- Üye
- Mesajlar: 142
- Kayıt: 29 Nis 2005 10:03
- Konum: İstanbul
- İletişim:
Arkadaşlar, programcılık tekniği açısından doğru mudur bilmiyorum ama bişekilde çözdüm problemi... tank nesnesini thread'in destroy bölümünde değil de OnTerminate property'sinin gösterdiği bir prosedür içinde yokediyorum... Problem çıkmıyor... Saygılar, sevgiler...
29.04.2005 tarihi itibariyle Delphi öğrenmeye başlayan yeni bir kullanıcı sayılabilirim.