Perl Tk, Windows, blockierende Funktionen
Hallo
Nach der Eingabe der Daten für FTP wird eine Dateiliste aus einem
festen Verzeichnis geholt und anschließend maximal 200 Dateien.
Bei diesem Vorgang blockiert das Fenster, keinerlei Ausgaben sind
mehr möglich. Ich nehme an, daß ich hier mit einem Thread arbeiten
muß.
Gibt es dafür Beispiele?
Alternativ könnte ich in der Funktion auch immer wieder die
MessageQueue anstoßen. Wie kann ich das machen?
--
Schönen Gruß aus dem Bergischen Land
Robert
Re: Perl Tk, Windows, blockierende Funktionen
Robert Berghaus schrieb:
> Hallo
>
> Nach der Eingabe der Daten für FTP wird eine Dateiliste aus einem festen
> Verzeichnis geholt und anschließend maximal 200 Dateien.
> Bei diesem Vorgang blockiert das Fenster, keinerlei Ausgaben sind mehr
> möglich. Ich nehme an, daß ich hier mit einem Thread arbeiten muß.
> Gibt es dafür Beispiele?
Hallo,
Du musst darauf achten, dass Tk erst geladen wird, wenn die Threads erzeugt
sind. (Also kein 'use'). Tk darf nur aus dem eigenen Thread angesprochen werden.
Hier ist ein simples Beispiel:
use warnings;
use strict;
use threads;
use threads::shared;
my $var =1;
share $var;
my $data ;
share $data;
my [at] threads;
push [at] threads, threads->create(\&thread);
tk_thread();
$_ -> join for [at] threads;
print "threads joined\n";
sub thread{
my $counter = 0;
while (1){
if ($var==1){
print "thread doing work\n";
{
lock $data;
$data = $counter++;
}
sleep (1);
}elsif($var == 0){
print "thread waiting\n";
sleep(1);
}else{
print "thread finished\n";
return;
}
}
}
sub tk_thread{
require Tk;
Tk->import;
my $mw = tkinit();
my $text = $mw->Text->pack;
$mw->Button(-text => 'start_stop',
-command => sub {{lock $var;
$var = $var? 0 : 1
}
},
)->pack;
$mw->Button(-text => 'beenden',
-command => sub{{lock $var;
$var = -1;
$mw->destroy;}
},
)->pack;
$mw->repeat(100,sub{{lock $data;
$text->insert('end', $data."\n") if $data ;
$data = '';
}
} );
MainLoop();
}
> Alternativ könnte ich in der Funktion auch immer wieder die MessageQueue
> anstoßen. Wie kann ich das machen?
>
$mw->update;
Grüße, Christoph
--
use Tk;use Tk::GraphItems;$c=tkinit->Canvas->pack;push [at] i,Tk::GraphItems ->
TextBox(text=>$_,canvas=>$c,x=>$x+=70,y=>100)for(Just=>anoth er=>Perl=>Hacker);
Tk::GraphItems->Connector(source=>$i[$_],target=>$i[$_+1])fo r(0..2);
$c->repeat(30,sub{$_->move(0,4*cos($d+=3.16))for( [at] i)});MainL oop
Re: Perl Tk, Windows, blockierende Funktionen
Hallo Christoph
Ich werde beides morgen mal probieren. Danke.
Ch Lamprecht schrieb:
> Robert Berghaus schrieb:
>> Hallo
>>
>> Nach der Eingabe der Daten für FTP wird eine Dateiliste aus einem
>> festen Verzeichnis geholt und anschließend maximal 200 Dateien.
>> Bei diesem Vorgang blockiert das Fenster, keinerlei Ausgaben sind mehr=
>> möglich. Ich nehme an, daß ich hier mit einem Thread arbeiten muß=
=2E
>> Gibt es dafür Beispiele?
>
> Hallo,
>
> Du musst darauf achten, dass Tk erst geladen wird, wenn die Threads
> erzeugt sind. (Also kein 'use'). Tk darf nur aus dem eigenen Thread
> angesprochen werden. Hier ist ein simples Beispiel:
>
> use warnings;
> use strict;
>
> use threads;
> use threads::shared;
>
> my $var =3D1;
> share $var;
> my $data ;
> share $data;
>
> my [at] threads;
>
> push [at] threads, threads->create(\&thread);
> tk_thread();
> $_ -> join for [at] threads;
>
> print "threads joined\n";
>
>
> sub thread{
> my $counter =3D 0;
> while (1){
> if ($var=3D=3D1){
> print "thread doing work\n";
> {
> lock $data;
> $data =3D $counter++;
> }
> sleep (1);
> }elsif($var =3D=3D 0){
> print "thread waiting\n";
> sleep(1);
> }else{
> print "thread finished\n";
> return;
> }
> }
> }
> sub tk_thread{
> require Tk;
> Tk->import;
> my $mw =3D tkinit();
> my $text =3D $mw->Text->pack;
> $mw->Button(-text =3D> 'start_stop',
> -command =3D> sub {{lock $var;
> $var =3D $var? 0 : 1
> }
> },
> )->pack;
> $mw->Button(-text =3D> 'beenden',
> -command =3D> sub{{lock $var;
> $var =3D -1;
> $mw->destroy;}
> },
> )->pack;
> $mw->repeat(100,sub{{lock $data;
> $text->insert('end', $data."\n") if $data ;
> $data =3D '';
> }
> } );
>
> MainLoop();
> }
>
>
>> Alternativ könnte ich in der Funktion auch immer wieder die
>> MessageQueue anstoßen. Wie kann ich das machen?
>>
>
>
> $mw->update;
>
> Grüße, Christoph
>
--
Schönen Gruß aus dem Bergischen Land
Robert
Re: Perl Tk, Windows, blockierende Funktionen
"Robert Berghaus" <Robert.Berghaus [at] gmx.de> schrieb im Newsbeitrag
news:c1.2bm.35r7W5$LTX [at] TPA31p-os2.robe-edv.lokal...
> Hallo
>
> Nach der Eingabe der Daten für FTP wird eine Dateiliste aus einem festen
> Verzeichnis geholt und anschließend maximal 200 Dateien.
> Bei diesem Vorgang blockiert das Fenster, keinerlei Ausgaben sind mehr
> möglich. Ich nehme an, daß ich hier mit einem Thread arbeiten muß.
Vielleicht geht es auch einfacher. Probier mal die folgenden Möglichkeiten:
1. Möglicherweise beschäftigen die FTP-Transfers deinen Rechner so sehr,
dass der Mainloop keine Chance hat, Events zu verarbeiten. Dann solltest du
in hinreichend kurzen Abständen update aufrufen. Wenn die einzelnen
Transfers schnell genug sind, genügt ein update nach jedem Transfer.
2. Möglicherweise wartet dein Programm in einem Callback auf das Ende der
Transfers. Dann könntest du die Transfers in ein nicht blockierendes
Toplevel auslagern, so ähnlich wie bei dem Modul zur Anzeige von
Fortschrittsmeldungen, das ich dir gestern geschickt habe. Ein update nach
jedem Transfer kann auch hier nicht schaden.
HTH.
Gruß
Klaus
Re: Perl Tk, Windows, blockierende Funktionen
Hallo Christoph
Ch Lamprecht schrieb:
> Robert Berghaus schrieb:
>> Hallo
>>
>> Nach der Eingabe der Daten für FTP wird eine Dateiliste aus einem
>> festen Verzeichnis geholt und anschließend maximal 200 Dateien.
>> Bei diesem Vorgang blockiert das Fenster, keinerlei Ausgaben sind mehr=
>> möglich. Ich nehme an, daß ich hier mit einem Thread arbeiten muß=
=2E
>> Gibt es dafür Beispiele?
>
> Hallo,
>
> Du musst darauf achten, dass Tk erst geladen wird, wenn die Threads
> erzeugt sind. (Also kein 'use'). Tk darf nur aus dem eigenen Thread
> angesprochen werden. Hier ist ein simples Beispiel:
>
[Beispiel]
Gibt es für Threads eine lesbare Dokumentation?
In meinem Programm kann ich das so nicht einsetzen, da ich erst in
einem Eingabefenster die FTP Zugangsdaten abfrage und dann erst
den Import anstoße. Vielleicht kann ich den ja auch als
Arbeitsthread beim Start erzeugen und immer wieder für
verschiedene Aufgaben benutzen. Zunächst reicht mir aber $mw->update!
>
>> Alternativ könnte ich in der Funktion auch immer wieder die
>> MessageQueue anstoßen. Wie kann ich das machen?
>>
>
>
> $mw->update;
Das nehme ich erstmal.
--
Schönen Gruß aus dem Bergischen Land
Robert
Re: Perl Tk, Windows, blockierende Funktionen
Hallo Klaus
K. Wittrock schrieb:
>
> "Robert Berghaus" <Robert.Berghaus [at] gmx.de> schrieb im Newsbeitrag
> news:c1.2bm.35r7W5$LTX [at] TPA31p-os2.robe-edv.lokal...
>> Hallo
>>
>> Nach der Eingabe der Daten für FTP wird eine Dateiliste aus einem
>> festen Verzeichnis geholt und anschließend maximal 200 Dateien.
>> Bei diesem Vorgang blockiert das Fenster, keinerlei Ausgaben sind mehr=
>> möglich. Ich nehme an, daß ich hier mit einem Thread arbeiten muß=
=2E
>
> Vielleicht geht es auch einfacher. Probier mal die folgenden Möglichk=
eiten:
>
Es geht einfacher.
> 1. Möglicherweise beschäftigen die FTP-Transfers deinen Rechner so =
sehr,
> dass der Mainloop keine Chance hat, Events zu verarbeiten. Dann solltes=
t
> du in hinreichend kurzen Abständen update aufrufen. Wenn die einzelne=
n
> Transfers schnell genug sind, genügt ein update nach jedem Transfer.
>
Jein, meinen Rechner nicht, wohl aber die SPS.
> 2. Möglicherweise wartet dein Programm in einem Callback auf das Ende=
> der Transfers. Dann könntest du die Transfers in ein nicht blockieren=
des
> Toplevel auslagern, so ähnlich wie bei dem Modul zur Anzeige von
> Fortschrittsmeldungen, das ich dir gestern geschickt habe. Ein update
> nach jedem Transfer kann auch hier nicht schaden.
Ja. Ich versuche mal kurz zu erklären, was dieser Programmteil macht.
=DCber das Menü (Hotkey Strg-o) wird ein Toplevel Fenster aufgebaut,
in welchem die FTP Zugangsdaten abgefragt werden; dann geht es
über einen Button weiter und in diesem Callback werden alle 200
Dateien von der SPS auf den Rechner geholt. Hier hatte der
Mainloop keine Chance, irgendwas zu machen. Jetzt rufe ich bei
jeder Datei auch update auf und die Statuszeile wird ihrem Namen
gerecht. Da die SPS nach ca. 45 Dateien lange Pause macht (ca.
20-30 Sekunden) bringt das in der Pause natürlich nichts, sonst
aber wohl.
Auch wenn ich das jetzt auslagere, blockiert ftp->get trotzdem. Ob
ich da überhaupt was dran machen kann, weiß ich jetzt noch nicht.
Hast Du bei dem Modul, welches Du mir geschickt hast vielleicht
etwas vergessen?
--
Vielen Dank und schönen Gruß aus dem Bergischen Land
Robert
Re: Perl Tk, Windows, blockierende Funktionen
Robert Berghaus schrieb:
> [Beispiel]
> Gibt es für Threads eine lesbare Dokumentation?
Hallo,
'perldoc threads'
'perldoc threads::shared'
'perldoc Thread::Queue'
Grüße, Christoph
--
use Tk;use Tk::GraphItems;$c=tkinit->Canvas->pack;push [at] i,Tk::GraphItems ->
TextBox(text=>$_,canvas=>$c,x=>$x+=70,y=>100)for(Just=>anoth er=>Perl=>Hacker);
Tk::GraphItems->Connector(source=>$i[$_],target=>$i[$_+1])fo r(0..2);
$c->repeat(30,sub{$_->move(0,4*cos($d+=3.16))for( [at] i)});MainL oop