Threat içinden form nesnelerine ait eventlar oluşturmak

Başlatan bunalmis, 15 Nisan 2010, 20:29:20

z

Nihayet amatörce de olsa threat tipi programlar yazmaya başladım. Ancak şöyle bir sorunum var ve çözüm bulamadım.

Aşağıdaki gibi bir program hayal edin.

Programı başlattığımızda bir threat procedure başlatılıyor ve bu procedure sonsuz döngüde 0 dan 100 e kadar sayıyor. 100 de tekrar sıfırlıyor.

Amacım bu su sayıcının her sıfır oluşunda form üzerindeki bir butonun click eventini tetikletmek.

Bu tetikleme işlemini nasıl yaparım.

Doğrudan iligili eveti çağırmak işime gelmiyor.

Örneğin Form1.Buton1.click(nil);

dersem threat içinden çıkılp forma ait procedüre geçiliyor. Bu da beraberinde critik değişkenlerle çalışmayı gerektiriyor.
Halbuki ben sanal bir mouse bir buton üzerine gelmiş ve tıklamış gibi olsun istiyorum.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

z

Threat içinde Form1.Button2.Click  şeklinde komut işletebileceğimi gördüm.

Buda yapmak istediğim şeyin ta kendisiydi.

Yalnız tamam sistem istediğim gibi çalışıyor sayaç her sıfır olduğunda buton2 event oluyor ve bu butona ait procedure içinde sorunsuz şekilde form üzerindeki tüm nesnelerin renkleriyle text değerleriyle vs oynayabiliyorum.

Ancak nadiren de olsa hata oluyor ve cpu registerleri geliyor. İllegal bir alana ulaşıldı tipinde bir mesaj.

Bu mesajın gelmesini engellemek için ne yapabilirim bu mesaj neden geliyor?

Eğer böyle değil de form nesnelerinin ıvır zıvır propertylerini thread içinden değiştirseydim zaten sistem kısa sürede bahse konu hata mesajına benzer mesaj çıkartıyor. o yüzden threat içinden tetikleme yoluna gittim.

Normalde bu tip işleri wswsx timer ile yapıyorum demişti. Ancak timer olayını sevmedim çünkü yavaş kalıyor. Ben dilediğim an dilediğimi yapabilmeliyim.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

orhanc

i'm doing nothing... Giddy Up  http://www.drorhan.com

z

Birde onu deneyeyim.

Aldığım hata mesajı access violation at 0x......

Bana e^st de diyebilirsiniz.   www.cncdesigner.com

controller

Muhtemelen aldığınız hata bir nesneye aynı anda iki thread in erişmek istemesinden kaynaklanmaktadır. Normalde thread ler arası işlemler doğrudan çağırmak yerine mesajlaşma ile yapılır. Veya "Mutex", "Critical Section" gibi kaynak paylaşım yöntemlerini kullanmalısınız.

Konu ile ilgili birkaç sayfa;

http://stackoverflow.com/questions/438945/cross-thread-communication-in-delphi

http://stackoverflow.com/questions/229630/delphi-multi-threading-message-loop#229808

Hesabım OG tarafından haksız bir şekilde pasif yapılmıştır.

z

Mutexlere bakmadım ama criticalsection hakkında bir şeyler öğrendim.

Yalnız ulaşmak istediğim bazı değişkenlere windows da erişiyor. Eğer erişmek istediğim değişkene sadece benim farklı threadlerim erişiyor olsaydı onları kolayca yönetebilirdim.

Ancak işin içine windows da girince nasıl olacak bunu anlamadım.

Mesela form üzerindeki bir nesnenin caption değerini threat içinden peryodik olarak değiştiriyor olalım.

Bir yandan da formu  minimize maximize edelim. Bu durumda işletim sistemi (ana formu yöneten ıvır zıfır programlar) bu caption değerlerini değiştirecek bende thrat içinden değiştireceğim. Burdaki çatışmaya nasıl engel olunacak bunu anlayamadım.

Bana e^st de diyebilirsiniz.   www.cncdesigner.com

z

Bu karşılaştığım hata mesajı, program çalıştıktan yarım saat sonra falan ortaya çıkıyor.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

controller

Alıntı yapılan: bunalmis - 15 Nisan 2010, 22:47:31

Yalnız ulaşmak istediğim bazı değişkenlere windows da erişiyor. Eğer erişmek istediğim değişkene sadece benim farklı threadlerim erişiyor olsaydı onları kolayca yönetebilirdim.

Ancak işin içine windows da girince nasıl olacak bunu anlamadım.

Mesela form üzerindeki bir nesnenin caption değerini threat içinden peryodik olarak değiştiriyor olalım.

Bir yandan da formu  minimize maximize edelim. Bu durumda işletim sistemi (ana formu yöneten ıvır zıfır programlar) bu caption değerlerini değiştirecek bende thrat içinden değiştireceğim. Burdaki çatışmaya nasıl engel olunacak bunu anlayamadım.

Böyle bir sorun olduğunu düşünmüyorum. Çünkü siz programınızı başlattığınızda zaten bir adet main (veya user interface) thread oluşuyor. Sizin dediğiniz gibi bir problem olsaydı, kendinizin oluşturduğu bir thread olmadan yazdığınız programda da aynı sorun olması gerekirdi.

Hesabım OG tarafından haksız bir şekilde pasif yapılmıştır.

z

Haklısın o zaman ben bir şeyi eksik yapıyorum. Ama eksik olan şey ne bilmiyorum.

Yaptığım olay aynen şu.

Sayaç bir thread fonksiyonu. Yaptığım tek şey bunu başlatmak.
Bu da Buton1 i clickliyor. Buton1 click eventi de static label üzerine bir şeyler yazıyor.

Procedure Sayac;
var i:integer;
begin
         while (true) do
            begin
               i:=(i+1) and 127;
               if i=0 then Form1.Button1.Click
            end;
end;

Eğer thread içine sleep eklersem hata hemen değilde 10 dk sonra yada yarım saat sonra ortaya çıkıyor.

Sonuçta çakışma olayı bir şekilde ertelenmiş oluyor.



end
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

z

Threat ustası yokmu?

Yapmak istediğim olay aynen yukarıdaki gibi çok basit bir uygulama. Buton1 click de aynen aşağıdaki gibi.

Procedure Tform1.Buton1.click(sender: Tobject);
begin
          label1.caption:=inttostr(Z);  // Z global bir değişken
          inc(Z);
          label1.refresh;
end;
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

controller

Bu şekilde bir kullanımın herzaman olmasa da hata vermesi normal. Thread ler arası iletişim için mesajlaşma kullanmalısınız.
Veya delphide nasıl yapılır bilmiyorum ama kullanacağınız nesneyi thread e parametre olarak geçirip, thread içinde kullanmayı deneyebilirsiniz.

Delphi kullansaydım size çalışan bir örnek verirdim ancak c ve türevleri dışında programlama dili kullanmıyorum.

Hesabım OG tarafından haksız bir şekilde pasif yapılmıştır.

t2

Alıntı yapılan: bunalmis - 15 Nisan 2010, 23:31:52
Threat ustası yokmu?
Var da bu işi bedavaya yapmak istemiyor. Forum göçmeden önce bir örnek vermiştim. Mesajlaşma ile çok güzel oluyor. Şuan yaptım aynı metodu kendi işlerimde çatır çatır kullanıyorum. Mesajı gönderdin eğer karşı taraf bunu almazsa, Gmönderen, mesaj alınana kadar bekler. Yani gönderici thread donar. Onu gidermek için her  mesajı ayrı thread ile  yolluyorum. Asıl thread işine devam ediyor hiç kesilmiyor.

Öte yandan asıl thread içinde bir nesne var (receiver)  o da gelen mesajları saygıda kusur etmeden alıyor, yine işine devam ediyor.

z

Bedava değilse ne kadara olur ne istiyorsun?

Bana uyar.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

hasangurlek

Alıntı yapılan: bunalmis - 15 Nisan 2010, 23:23:44
Haklısın o zaman ben bir şeyi eksik yapıyorum. Ama eksik olan şey ne bilmiyorum.

Öncelikle nesneyi oluşturduğunuz thread o nesnenin maliki yani sahibidir. Eğer nesneyi sahibinin dışında diğer processler tarafından erişebilecek şekilde oluşturduysanız o nesneye erişimi kontrol altında tutmak zorundasınız ki bu kontrol altında tutma işlemine thread-safe deniyor. Çok küçük bir ihtimal olsada aynı nesneye farklı processler aynı anda erişmeye çalıştığında ortaya hata çıkması gayet normaldir. Bu linke bakarsanız thread-safety mantığı çok sade bir şekilde anlatılmış ve dot dillerinden örnekler verilmiş ; http://msdn.microsoft.com/en-us/library/ms171728%28VS.80%29.aspx

Makineniz tek CPU ya sahip olduğu için şanslısınız çünkü tüm donanımlara erişim bu tek CPU üzerinden sırayla yapılıyor ve sadece hata mesajı alıyorsunuz. Eğer ki makinenizde birden fazla CPU olsaydı ve örneğin aynı anda ortak kullanılan RAM bellekteki bir adrese ulaşmaya çalışsalardı sistem çökmesinden donanım arızasına kadar pek çok sonuca yol açabilecek lojik seviyede elektriksel bir çakışma meydana gelecekti. Microsoft birden fazla CPU ile çalışan makinelerde çakışma kontrolünün yapılmadığını açıkça bildiriyor ve tüm sorumluluğu multi-thread yazılımı geliştiren kod sahibine yıkıyor.
http://www.cyber-warrior.org, Although they like whiteness, sometimes twilight is required...  Hala evlilermi bilinmez ama kesinlikle artık uygun değiller !!!

t2

Alıntı yapılan: bunalmis - 16 Nisan 2010, 00:40:59
Bedava değilse ne kadara olur ne istiyorsun?
Bana uyar.
Bu çiplerle çok uğraştım.  Tecrübem var. Önce sana hap gibi bir demo yaparım. formun üzerine buton gibi bir nesne koyacaksın hepsi o. Threadi içinde. sen sadece "OnData" olayını değerlendirirsin. istediğin diğer olayları tetiklersin.  İlaveten OnConnect OnDisconnect gibi bazı olaylar da ekleyebilirim

Nesne senin cihazı nasıl bulacak? VendorID, ProductID diye propertysi olacak. Onları set edip "hadi aslanım" diyeceksin. İşlem tamam.  Çalışma esnasında aygıtı sök tak yaparsan sorun olmayacak. Hangi USBye takarsan tak bulacak.

Elbette direct driver kullanılacak seriport emulasyonuyla işin olmaz.

Şimdi gelelim maliyetine. Maliyet sudan ucuz. 100USD  gibi düşündüm.  Bu nesnenin bir lisans mekanizması olacak.  Key girilecek. ( tabi key girmenin de bir formaitesiolacak lisans sahibine bildirceğiz) Tek sefere mahsuslisans alınacak. istediğin kadar kullanacaksın.

Neyse ben demoyu yapayım da senin alman şart değil. Etrafta bu FTDI çipi ile iş yapan fakat zorlanan kişiler vardır elbet birileri ister diye düşünüyorum.  Dünya çapında satılır.