PDA

Tam Sürümünü Görmek İçin : for dongusunden cikmak


yastasinane
24/08/2005, 00:53
slmlar,
builder kullanarak yazdigim bir programda, bir butonla for dongusu basliyor. diger bir butonla bu islemin durdurulabilmesini yapmaya calisiyorum ama IdAntiFreeze kullanmama ragmen dongu bitmeden istegime cevap vermiyor.

yapabilecegim bisi var mi, yada cozum onerisi?

iyi calismalar...


yastasinane
24/08/2005, 01:25
soyle bi cozum buldum;
bir if denetlemesi soktum donguye, onceki bir deger degismisse ki ben bunu, islemi durdurmak istedigimde bi butonla degistiriyorum yani iptal butonuyla, if'den break donuyor ve durduruluyor.

yinede baska cevabi olan varsa incelemek isterim.

iyi calismalar...

mr1yh1
24/08/2005, 01:30
....

thread kullanımı ile de çözüm mümkün.

yastasinane
24/08/2005, 01:39
nasil anlayamadim, ornek verebilirmisin??

yastasinane
24/08/2005, 01:55
bool kullanip hThread=true, false gibisinden birsey mi?

mr1yh1
24/08/2005, 04:46
buna C++ de örnek veremem,
standart C++ de Thread yok , ama CBuilderin kütüphanelerinde var.
Java örneği vereyim. içinde GUI olduğu için kod biraz kalabalık ama mantığı basit. start , resume , suspend kısımları işi hallediyor.
başla tuşu döngüyü başlatıyor.
duraklat tuşuna basınca döngüyü askıya alıyor.. ( kırıp çıkmak da mümkün)
daha sonra tekrar aynı tuşa basınca döngü kaldığı yerden devam ediyor.
bu askıya alma işini thread kullanmadan yapamazsın.

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class ThreadTest extends JFrame {

public ThreadTest(){
setSize(300,300);
setDefaultCloseOperation(EXIT_ON_CLOSE);
function = new ThreadedFunction( labelScore );
//pencereye label butonları ekle
JPanel panelButton = new JPanel();
panelButton.add(buttonStart);
panelButton.add(buttonPause);
getContentPane().add(labelScore , BorderLayout.CENTER);
getContentPane().add(panelButton , BorderLayout.SOUTH);
//buttonlara işlevlerini ekle
buttonStart.addActionListener( new ActionListener() {
public void actionPerformed( ActionEvent e ){
// thread bu tuşa basılınca başlayacak
//sadece 1 tane istiyorum
if ( function.isAlive() ) return ;
else function.start();//fonsiyon çalışmaya başladı.
}
});

buttonPause.addActionListener( new ActionListener() {
public void actionPerformed( ActionEvent e ){
// fonksiyonu duraklat, ya da devam ettir.
// burada döngüden çıkmıyoruz onu askıya alıyoruz
if ( suspended ) {
function.resume();//depreceted method resume
buttonPause.setText("duraklat");
suspended = false;
}
else {
function.suspend();//depreceted method suspend
buttonPause.setText("devam et");
suspended = true;
}
};
});

}
//start ve pause buttonları
private JButton buttonStart = new JButton("başla");
private JButton buttonPause = new JButton("duraklat");
// threadin durduğu değeri yazacağımız label
private JLabel labelScore = new JLabel("000",JLabel.CENTER);
//1 thread yaratıcaz.
private ThreadedFunction function ;
private boolean suspended = false;


public static void main(String[] args) {
ThreadTest test = new ThreadTest();
test.setVisible(true);
}

}

class ThreadedFunction extends Thread{

public ThreadedFunction ( JLabel label ) {
this.label = label;
}
public void run(){
// döngü buraya yerleşecek.
for ( int score = 0 ; score < 1000000 ; score++ ){
label.setText( Integer.toString(score) );
try {
sleep(1000); // 1 saniyede bir ekrana score u yaz yaz..
} catch (InterruptedException ex) {
}
}
}

private JLabel label ;
}

karamemed
24/08/2005, 08:11
soyle bi cozum buldum;
bir if denetlemesi soktum donguye, onceki bir deger degismisse ki ben bunu, islemi durdurmak istedigimde bi butonla degistiriyorum yani iptal butonuyla, if'den break donuyor ve durduruluyor.

yinede baska cevabi olan varsa incelemek isterim.

iyi calismalar...

Böyle sorunun çözüldüğüne emin misin? Yanlış bilmiyorsam o for'dan çıkmadan sistemin olaylara cevap verememesi lazım. Tabi yanılıyor da olabilirim.

mr1yh1
24/08/2005, 08:29
+1
ancak bu döngü, GUI dışında oluşturulmuş ise oluyor.

import javax.swing.*;
import java.awt.event.*;
import java.awt.*;

public class Test33 extends JFrame {
public Test33() {
setSize(200, 200);
panelButton.add(buttonStop);
getContentPane().add(panelButton, BorderLayout.CENTER);
buttonStop.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
clicked = true;
}
});

}
private boolean clicked = false;
public static void main(String[] args) {
Test33 test33 = new Test33();
test33.setDefaultCloseOperation(EXIT_ON_CLOSE);
test33.setVisible(true);//gui thread başladı
test33.foo();//ayrı çalışıyor...
}

private void foo(){
while (true) {
if (clicked) //button bu değeri değiştiremezse çıkış yok.
{
System.exit(1);
}
}
}
private JButton buttonStop = new JButton("stop");
private JPanel panelButton = new JPanel();
}

darkshadow
24/08/2005, 09:24
if denetlemesinden önce

Application->ProcessMessages();

Bu komutu çalıştırın. Program kendine gelen mesajları işleyecek butona basıldığında atanan değişkenide görecektir.Yalnız bu pek doğru bir kullanım şekli değil. Bende Thread kullanmanızı öneririm.

yastasinane
24/08/2005, 20:30
zaten Application->ProcessMessages(); kullandigim icin diger bir buton deger degistirebiliyor. cozumu bu sekilde bulmustum.

ama darkshadow dogru bi kullanim degil yazmissin, nedenini aciklayabilmen mumkun mu?

mr1yh1;
yazdigin kodlari tamamen okudum, mantigini anliyorum, ancak c++ 'da thread kullanimi uzerine bir bilgim yok. arastiricam.

tesekkurler...

shark_hack
24/08/2005, 23:26
valla o kadarda acil bişiyse vede önemli bişeyse :-)
"goto" kullan...
ne biliyim goto kullanmak ssanki programcılara hayat mebah meselasi gibi geliyor ama bu gibi durumlarda eğer kodlamanın yapısını tam olarak bilmiyorsan işin içinden rahat bişekilde çıkıp başka kısımlara zaman ayırabiliyorsun...

neurorebel
25/08/2005, 00:58
anti-goto'cular derneği kurmak lazım :) eheh...

mr1yh1
25/08/2005, 01:47
goto ile nasıl çözebilirsiniz ki bu problemi ..

Sabahi
25/08/2005, 05:16
goto ile cozulmez. Aslinda herhangi bir cozum uretmeden once yastasinane arkadasin uygulamasi dogru mu degil mi ona bir karar vermek lazim ki for dongusunun ne tur bir islem yaptigini bilmeden kesin bir sey soylemek zor. Su anda aklima gelen ilk sakinca donguye girmek icin baslatma dugmesine basilmadan once durdur dugmesine basilabilecegi. Eger durdur dugmesi tiklandiginda butun yaptigi if cumlesinde kullanilan degiskenin degerini degistirmekse muteakiben tiklanan baslatma dugmesi donguden zamanindan once cikilmasina neden acabilir. Tabi bu sadece akilda bulundurulmasi gereken ama cok kompleks bir cozume ihtiyac duyulmayan bir durum. Bir baska sakinca windows mesajlarinin kuyruklandirilmis olmasinin yaratabilecegi gecikme ki buyuk bir ihtimalle kaale alinmayacak kadar onemsiz bir durum.

PUNK
26/08/2005, 06:34
thread kullanmadan olmazmı bu iş :)

asoza
04/09/2005, 02:01
Arkadaşlar basit bir for döngüsünden kurtulmak için thread lar, goto lar. Yapmayın etmeyin.
En güzel çözümü yine kendisi bulmuş.
boolean bir değişkenle döngüden çıkmayı istediği an için yapabilir.
Bir diğer konu da Application->ProcessMessages hakkında.
Ben prensip olarak her döngünün kalıbında kullanırım.
Sistemi zora sokmadan programın stabil çalışması için olmazsa olmaz kodlardan bence.
Hatta sistemle paslaşılan bazı durumlarda mutlaka gereklidir. Kusursuz olduğu halde sorun çıkartan kod satırları arasında da yine sisteme nefes aldırmak adına iyi bir tercihtir.


#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;

bool b = false;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
b = false;
for(int i = 0; i < 10000 && !b; i++) {
Caption = String(i);
Application->ProcessMessages();
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
b = !b;
}
//---------------------------------------------------------------------------

Euclides
04/09/2005, 10:40
Sistemi zora sokmadan programın stabil çalışması için olmazsa olmaz kodlardan bence.
Hatta sistemle paslaşılan bazı durumlarda mutlaka gereklidir. Kusursuz olduğu halde sorun çıkartan kod satırları arasında da yine sisteme nefes aldırmak adına iyi bir tercihtir.

ne desem boş

Volkan Uzun
04/09/2005, 10:56
her dongude processmessage yapmak mi ?
sanirim piv makineye bu sunu demek gibi bisi :
hizlica kos ama her 1 saniyede bir dur arkana bak.
amacin islemlerini hizlica bitirmek olmali, eger ayni anda baska bir is yapmak istiyorsan, bunu thread e tasimakta bence cok mantikli.
sistemle paslasmaktan kastin nedir ? eger sisteme mesaj gonderip mesaj almak ise, asenkron calismalar tercih edilmeli

asoza
04/09/2005, 14:44
Ne yapacaksınız? Thread oluşturdunuz ve orada da bir for döngüsü kurdunuz. Onu istediğiniz zaman kesebilmek için ona da ayrı bir thread mı açacaksınız ve onada bir başka...
Ben mi soruyu yanlış okudum yoksa siz mi farklı bişeyler gördünüz? Soruda bir for döngüsünden ikinci bir butonla kurtulmaktan bahsediliyor. Kulağı göstermenin programlamada seçeneklerinin bol olduğunu biliyorum ama bu kadarına da pes diyorum. Fantazi gibi bişi.. Bende uyandırdığı izlenim bu.
sanal_programcı, dostum, bulunduğum tüm forumlarda yapıcı olmanın dışında bir tutumum olmamıştır. olmaz da zaten.
Kullandığın cümlelerin teknik açılımındaki hataları vurgulamak adına; sistemlerin nasıl multi tasking çalıştığını biraz araştırmanı öneririm.
Örnek olarak ta senin verdiğin hiç uymamış.
Ben vereyim bir örnek ki bence multi tasking anlayışına sistem açısından cuk oturuyor.
Sistemi, tek hava çıkış borusu olan bir hava tankına benzet. Çalışan programları veya daha anlamlı olması açısından threadları (ki her program en az bir thread dan oluşur) denizin altında sistemin hava tankından nefes almaz zorunda olan dalgıçlar olarak değerlendir. Sistem sırasıyla ve priorty derecesine göre bu dalgıçlara hava veriyor. Yani işlemciyi kullandırıyor. Üstelik te terimi yanlış hatırlamıyorsam kuantalık zaman dilimleri kadar kısa süreli değiştiriyor hava verdiği threadı.
Birisi çıkmış, hava hortumunu kapmış bırakmak istemiyor. Application->ProcessMessages yapmıyor yani. Sistemin tüm ritmini kasıyor.
Bilmiyorum neyi ne kadar anlatabildim. Ama sistemi tanımadan programcı olunmaz. Ya da sistemi tanıdığın kadar programcısındır.
Eğer ölçmek istersen iki for döngüsünü teste alabilirsin. Birisi benim önerime uygun diğeri kara balta. farkın belirginleşeceğini umduğun bir işlemi yükle. İşlem tamamlandığında hiç fark olmadığını -neredeyse- görürsün zaten. Mikro saniyeler düzeyinde bir fark yakalarsan onuda sistem kararlılığı ve stabilitesi açısından feda edilen karlı bir zaman olarak değerlendirebilirsin.
Bir soru sormak istiyorum.
Virüs tarama programları neden 50 ayrı koladan arayıp ta tarama zamanını kısaltmıyorlar acaba. Üstelik aralarında bu önemli bir rekabet unsuru.
Cevabını da vereyim. İsterse her klasörün içindeki dosyaları ayrı bir thread a tarattırsın totalde tarama zamanı aynı kalacaktır. Bu örneğimdeki hava tankı ve borusuyla ilgili bir durumdur.
euclides sizin mesajınızdan olumlu olumsuz bir sonuç çıkaramadığım için yorum yapamıyorum.

mr1yh1
04/09/2005, 17:36
@asoza
bu durumda , tüm kontrolü döngünün içerisinde yapman gerekir , yani döngünün , kendine yönelik olayları, ve vereceği tepkiyi bilmesi gerek ,oysa bu döngünün sorumluluğu değil.. .
arkadaş farklı bir düğme kullanmak istese, döngü kodu değişecek ( coupling ).. karmaşası bir yana, döngü kodunun yeniden derlenmesi lazım.

ileride programın değişik kısımlarının, döngüye müdahale etmesi gerekebilir, o zaman karmaşa büyür.
hatta bu kısımların application message loop u kullanması bile gerekmiyor. ( GUI mesajları olmayabilirler )

Euclides
04/09/2005, 19:03
Ben vereyim bir örnek ki bence multi tasking anlayışına sistem açısından cuk oturuyor.
Sistemi, tek hava çıkış borusu olan bir hava tankına benzet. Çalışan programları veya daha anlamlı olması açısından threadları (ki her program en az bir thread dan oluşur) denizin altında sistemin hava tankından nefes almaz zorunda olan dalgıçlar olarak değerlendir. Sistem sırasıyla ve priorty derecesine göre bu dalgıçlara hava veriyor. Yani işlemciyi kullandırıyor. Üstelik te terimi yanlış hatırlamıyorsam kuantalık zaman dilimleri kadar kısa süreli değiştiriyor hava verdiği threadı.
Birisi çıkmış, hava hortumunu kapmış bırakmak istemiyor. Application->ProcessMessages yapmıyor yani. Sistemin tüm ritmini kasıyor.
Bilmiyorum neyi ne kadar anlatabildim. Ama sistemi tanımadan programcı olunmaz. Ya da sistemi tanıdığın kadar programcısındır.
....
euclides sizin mesajınızdan olumlu olumsuz bir sonuç çıkaramadığım için yorum yapamıyorum.
Seninde dediğin gibi sistemi tanımadan programı olunmuyor. Task switching yapılırken biz benim işim işim bitti demiyoruz. Windows'un timer'i tick'ledimi cat ! task değişti :) sen bitirsende bitirmesende... Application->ProcessMessages ile sen başkalarına hava vermiyorsun.
Application->ProcessMessages şunu yapıyor

MSG msg;
GetMessage(&msg,NULL,NULL,NULL);
TranslateMessage(&msg);
DispatchMessage(&msg);

Sen sadece kendi mesajlarını tekrar işliyorsun. Başka birşey değil !
Eğer hava vermek istersen NtYieldExecution(ki bunda seçim OS'a kalmış takmayabilir) veya Sleep yapabilirsin. Yani sen istesende "hava hortumunu kapmış bırakmak istemiyor." gib bir şey yapamazsın. Task switching'i user-mode'dan durduramazsın.

Ne yapacaksınız? Thread oluşturdunuz ve orada da bir for döngüsü kurdunuz. Onu istediğiniz zaman kesebilmek için ona da ayrı bir thread mı açacaksınız ve onada bir başka...

Ne alaka ? 2 thread'ımız var 1'i diğerini kontrol ediyor... 3. bir thread'a ihtiyaç yok kontrol için. Ayrıca Bak: MSDN -> Synchronizing Execution of Multiple Threads

asoza
04/09/2005, 22:13
ilk uyarınıza katılıyorum. Tabii karanlıkta kalan kısımları da açıklasaydınız daha makul olurdu.
Neden uzun döngülerde sistemin kilitlenmeye uzanan bir sıkıntıya sürüklendiğini, neden programın bir süre sonra yanıt vermediğini, main threadımızın neden mesaj kuyruğuna bakamadığını (bu noktada bunun için thread önerdiğinizi yazabilirsiniz, ben daha basitini önerdim veya ilk önerene katıldım) açıklamalarınıza ekleseydiniz daha anlamlı olurdu. Basit bir processmessages açılımıyla neden tüm bu sıkıntılardan kurtulunduğunu da açıklasaydınız keşke.
Sadece for döngüsünü thread ile oluşturmayı veya sadece for için kanal açmayı mantıklı bulmuyorum. Sizin anlatımlarınızdan çıkardığım sonuçlardan birisi de şu; bırak for verdiğin işi yapsın, illede kesmek istiyorsan aç kanalı suspend, exit bitir. break sözcüğünü kodun akışında kullan ama keyfi çıkışlarda extra bir denetim ile döngüden çıkmak için tercih etme şık olmaz.
Tüm konuşulanları problem sahibinin sorusunu bir kere daha okuyup sonra değerlendirseydiniz keşke. Onun sorusundan bilgi seviyesini, anlayacağı dili değerlendirseydiniz. O günlerinizi düşünseydiniz.
Yukarıdaki mesajımda verdiğim kod en uygun koddur. Benim anlayışım budur. Benzer şekilde ve üslupta verilen tek örnek java kodu.
mr1yh1, thread sık kullandığım unsurlardan birisi. üslubuna ve görüşlerine katılıyorum. Son iki paragrafım ana fikrimin açılımı. Anlayacağını umuyorum.

karamemed
04/09/2005, 22:24
Bir soru sormak istiyorum.
Virüs tarama programları neden 50 ayrı koladan arayıp ta tarama zamanını kısaltmıyorlar acaba. Üstelik aralarında bu önemli bir rekabet unsuru.
Cevabını da vereyim. İsterse her klasörün içindeki dosyaları ayrı bir thread a tarattırsın totalde tarama zamanı aynı kalacaktır. Bu örneğimdeki hava tankı ve borusuyla ilgili bir durumdur.Ben bu olayın thread ile alakasını anlayamadım. Disk sistemdeki en yavaş bellektir. Sen bir giriş-çıkış istemi yaptığında (Diske erişim yani) senin thread kuyruğa atılır ve onun istemi hallolana kadar diğer threadlar kaç tur atarlar Allah bilir. Yani her klasör için bir thread oluşturmak yerine oturup ağlamak daha mantıklı bir seçim olacaktır. Bir milyon tane de thread oluştursan hepsi oturup giriş-çıkış işlemi sırasının kendisine gelmesinden başka bişi yapamazlar.

asoza
04/09/2005, 22:32
"totalde tarama zamanı aynı kalacaktır"
karamemed, ben farklı bişey mi demişim.

karamemed
04/09/2005, 22:37
Ben vardığınız sonucun değil, sonuca varış şeklinizin yanlış olduğundan bahsediyorum. Yani tank ve boru ile alakalı bir durum yok orda. Sorun diskin yavaşlığı. Aksi takdirde sizin daha çok boru sahibi olmanız daha çok hava alabilmeniz demek olacaktı değil mi?

Euclides
04/09/2005, 22:39
@karamemed:
+1

@asoza:
senin çözümünle tüm bu sıkıntılardan kurtulmadığımızın altını çizmek isterim.
2...
AV olayında öyledir, Fakat bizim problemimizde öyle değildir. Çünkü sen boşuna bir sürü işlem yaptırıyorsun. bakınız:sanal_programci'nın mesajında güzel örnek vermiş.

asoza
05/09/2005, 10:28
Euclides, siz öyle diyorsanız kafi.
karamemed, sistem çok görevli çalışmayı nasıl organize ediyor. Temel örnekle.
Gerçekte çok görevli çalışma var mıdır?
Euclides in "cat !" olarak açıkladığı borunun el değiştirmesi değil midir? Tekrar sırası gelene kadar cat edilen görev ne yapıyor. Elbette boru fazla olsaydı işler daha hızlı yürüyecekti. Disk ile bağlantısını her durumda açıklayamazsınız ki. Her görev disk üzerinde işlem yapıyor olamaz her halde. programlar bellekte çalışıyor. Bu varsayımla yazıyorum. AV örneğine atfen yazıyorsanız, o bir örnek tam uymamış olabilir. Ama anlatmak istediğimi açıklamaya yakın en azından.
Bir de +1, -20 gibi yaklaşımlarla konu şekillenecekse sorulan sorular havada kalacaksa bu topikten ben kendi adıma yararlanamıyorum.
Euclides in bir önceki mesajında yaptığı gibi alıntılarla sorularımı yanıtlamasını beklerdim. Tabii amaç üzüm yemekse.

Euclides
05/09/2005, 13:26
Euclides in bir önceki mesajında yaptığı gibi alıntılarla sorularımı yanıtlamasını beklerdim. Tabii amaç üzüm yemekse.
Amaç yol göstermek. Meslea bazı kişiler foruma mesaj atıyorlar "nasıl el yazısı tanıyan program yaparım ?" şimdi bu insanlara siz gidip 600 sayfalık bir yapay sinir ağları kitabını forumda anlatamazsınız. Fakat bak kardeşim yapay sinir ağı bir şey var sen bir arat amazonda dersiniz
Benimde bu konuları forumda derinlemesine anlatmam mümkün değil. hangi birini anlatayım ? windows internals mı!? Multi tasking OS design mı ?! Adamlar o kadar kitap yazmış sadece 1 konu üzerine. Eğer benim yazdığımda tıpkı onlar gibi 1 konuyu güzelce irdelemeyecekse yazdığım yazı fayda değil zarar doğrur. En zor öğrenme yanlış bilginin doğrusuyla değiştirilerek yapılan öğrenmedir. Hele hele insanların kendinden önceki mesajları okumaya bile tenezül etmediği, sadece "benim penisim sizlerinkinin 10 katı" demek için mesaj yazdığı bir grubda tips&tricks vermek bile imkansızdır.

aktasm
24/09/2005, 03:14
arkadaslar C derleyicileri adlı baslıgı incelerseniz sevinirim..

acehreli
24/09/2005, 07:01
aktasm, C derleyicileri adli basligi herkes gordu zaten. Lutfen konulari karistirmayalim.

Tesekkurler,
Ali