Merhabalar,
içinden bir türlü çıkamadığım bir sorunum var.
Seri porttan gelen bilgileri okuyup, ilgili bilgiyi veritabanında birtakım işlemlerle
sorgulayıp yine seri porttan göndermesi gereken bir program yazmaya çalışıyorum.
Veritabanı olarak firebird kullanıyorum.
Veritabanı sorgulanırken birçok tablodan veri sorgulaması ve gelen değerlere göre yeni
birtakım işlemler yapılması gerektiği için bir SP yazdım ve işlemi veritabanına
yaptırıyorum. SP parametre olarak seri porttan gelen değeri alıyor ve göndermem gereken
değeri döndürüyor.
Seri porttan gelen değerler, ne zaman ne sıklıkla geleceği belli olmayan şeyler olduğu için;
bu işlem için de bir thread oluşturdum.
Eğer bilgisayarda tek bir port varsa, 1 thread oluşturuluyor ve hızlı bir şekilde sorunsuz
çalışıyor. Ama eğer ikinci bir seri port kullanılmak istenirse, yeni bir thread
oluşturuluyor. Eğer 2 thread var ise bir süre çalışıp ikisi birden ölüyor.
Tespitime göre sorun veritabanından kaynaklanıyor.
Veritabanı işlemleri kaldırınca sorun yok.
SP içinde bolca sorgu ve kontrolün ardından bir dosyaya sonuç giriliyor. Ama aynı dosya
sorgulmanın da bir parçası.
Bağlantı için Zeos, IB, Dbexpress hepsini denedim ama sonuç değişmedi.
Dbexpress daha hızlı çalışıyor ama o da çöküyor.
Program çalışmaya devam ediyor aslında ama thread mefta oluyor.
Program system try kısmına yerleşerek çalışıyor.
Ana formda 4 adet (en fazla 4 port olacağı düşünülerek) theread değişkenim var. Her thread
kendi değişkeni üzerinden oluşturuluyor.
örn: Thread2:=PortDinle.Create(mHandle);
thread içinde ise
constructor PortDinle.create(const FormHandle:HWND);
Begin
inherited create(true);
fAnaFrmHandle:=FormHandle;
FreeOnTerminate:=True;
Resume;
End;
FormHandle, ana formla iletişim için kullanılıyor,
Database bağlantı nesnelerini ana form üzerine koydum,
her thread için kendi içinde execute bölümünde oluşturdum ama sonuç değişmedi.
Birşekilde kayıt kitlenmesi mi oluşuyor,
DeadLock mı luşuyo anlamadım.
Kısaca 2 thread aynı veritabanı üserinden select ve insert yapmaya çalışınca gümlüyor.
Ve bu işlemleri SP kullanarak yapıyorlar.
Her thread için ayrı SP çalıştırınca da sorun çözülmedi.
Yardımmm.....
multi Thread içinden veritabanı bağlantısı sorunu
Forum kuralları
Forum kurallarını okuyup, uyunuz!
Forum kurallarını okuyup, uyunuz!
Veritabanına bağlanırken her bir thread için TSession veya TSQLConnection'una kadar bütün DB componentlerini Thread içinde ayrı ayrı create etmelisin. Yani her bir Thread'in kendine ait ve de mümkünse kendi içinde create edilmiş TQuery, TDatabase ve TSession'u (BDE) veya TSimpleDataSet ve TSQLConnecton'u (dbExpress) olması gerekir.
İyi çalışmalar.
İyi çalışmalar.
Thread içerisinde, bağlantı için gerekli her nesneyi kendi içerisinde oluşturdum. Veri tabanı sorgulrını seri porttan veri geldikçe çelıştırıyorum. Bir thread çalışıyorsa sorun yok. Birden fazla thread yoğun bir şekilde çalışıyorsa sorun çıkıyordu.
fduman
"Thread çalışmaları yaparken aynı sorun ile karşılaşmıştım. Problem VT'ye bağlanırken yolu 'C:\DB\VT.FDB' olarak vermemdi. Network path verince sorun çözülmüştü. Firebird local file'larde multithread yapamaz. 'localhost:C:\DB\VT.FDB' olarak kullanman gerekir."
bu yöntem ilginçtir başta işe yaradı gibi gözüktü. Uzun süre kitlenme olmadı ama sonunda yine kitlendi.
Her thread için ayrı ayrı bağlanınca, aynı kayıtlara, aynı anda erişmeye çalışma durumu oluşuyordu ve sanırım bu durumda DeadLock denen hadise meydana geliyordu.
Sonuç olarak veritabanı bağlantısını thread içerisinden çıkarttım.
Ana forma koydum. Thread ana formun kendisi için ayrılmış header'ına mesaj gönderip istekte bulunuyor, gelen isteğe göre veritabanı sorgulamasını ana formdaki nesneler hallediyor. Böylece aynı anda her port dinlenebilmekle birlikde sadece 1 veritabanı bağlantısı oluşmuş oldu.
Hız biraz düştü ama, en azından sorunsuz çalışıyor.
Hız hala kabuledilebilir düzeyde olduğu için şu anda sorun çözülmüş gibi.
Teşekkür..
fduman
"Thread çalışmaları yaparken aynı sorun ile karşılaşmıştım. Problem VT'ye bağlanırken yolu 'C:\DB\VT.FDB' olarak vermemdi. Network path verince sorun çözülmüştü. Firebird local file'larde multithread yapamaz. 'localhost:C:\DB\VT.FDB' olarak kullanman gerekir."
bu yöntem ilginçtir başta işe yaradı gibi gözüktü. Uzun süre kitlenme olmadı ama sonunda yine kitlendi.
Her thread için ayrı ayrı bağlanınca, aynı kayıtlara, aynı anda erişmeye çalışma durumu oluşuyordu ve sanırım bu durumda DeadLock denen hadise meydana geliyordu.
Sonuç olarak veritabanı bağlantısını thread içerisinden çıkarttım.
Ana forma koydum. Thread ana formun kendisi için ayrılmış header'ına mesaj gönderip istekte bulunuyor, gelen isteğe göre veritabanı sorgulamasını ana formdaki nesneler hallediyor. Böylece aynı anda her port dinlenebilmekle birlikde sadece 1 veritabanı bağlantısı oluşmuş oldu.
Hız biraz düştü ama, en azından sorunsuz çalışıyor.
Hız hala kabuledilebilir düzeyde olduğu için şu anda sorun çözülmüş gibi.
Teşekkür..
fduman yazdı:Hala kilitleniyor ise thread yapını yanlış kurmuşsun. Kodu görmeden birşey söylemek pek mümkün değil.huradem yazdı: bu yöntem ilginçtir başta işe yaradı gibi gözüktü. Uzun süre kitlenme olmadı ama sonunda yine kitlendi.
thread yapını yanlış kurmuşsun. Kodu görmeden birşey söylemek pek mümkün değil

MultiThread olayı karışıktır biraz.Thread'e bulaşan herkes muzdarip bu tarz vakalardan.Firebird kullanmadığım için pek bilmem ama her durumda MultiThread desteklemesi lazım ki senin threadler bi işe yarasın öteki türlü yolla sırayla gitsin(Gerçi Niye sırasıyla yollayıp almıyorsun değerleri illa thread lazım değilki...)
- sadettinpolat
- Moderator
- Mesajlar: 2131
- Kayıt: 07 Ara 2003 02:51
- Konum: Ankara
- İletişim:
bircok thread ile birlikte ayni baglanti uzerinden firebird veritabanina ekleme , silme, guncelleme tarzi islemler yaptirdim. belirli bir sure duzgun giderken arasira transaction hatasi ya da veritabani okunamadi tarzi hatalari aldim. hata mesajlarini internette arastirdigimda sorunun winsock ile ilgili oldugu bilgisine ulastim. cozumu her thread icinde veritabanina ayri bir baglanti kurarak asmistim.