Perl Tk, Windows, blockierende Funktionen

Perl Tk, Windows, blockierende Funktionen

am 02.07.2007 13:54:24 von Robert Berghaus

Hallo

Nach der Eingabe der Daten für FTP wird eine Dateiliste aus einem=20
festen Verzeichnis geholt und anschließend maximal 200 Dateien.
Bei diesem Vorgang blockiert das Fenster, keinerlei Ausgaben sind=20
mehr möglich. Ich nehme an, daß ich hier mit einem Thread arbeiten=20
muß.
Gibt es dafür Beispiele?
Alternativ könnte ich in der Funktion auch immer wieder die=20
MessageQueue anstoßen. Wie kann ich das machen?

--=20
Schönen Gruß aus dem Bergischen Land
Robert

Re: Perl Tk, Windows, blockierende Funktionen

am 02.07.2007 17:09:25 von Ch Lamprecht

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 @threads;

push @threads, threads->create(\&thread);
tk_thread();
$_ -> join for @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@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(@i)});MainL oop

Re: Perl Tk, Windows, blockierende Funktionen

am 02.07.2007 19:55:21 von Robert Berghaus

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=20
>> festen Verzeichnis geholt und anschließend maximal 200 Dateien.
>> Bei diesem Vorgang blockiert das Fenster, keinerlei Ausgaben sind mehr=
=20
>> möglich. Ich nehme an, daß ich hier mit einem Thread arbeiten muß=

>> Gibt es dafür Beispiele?
>=20
> Hallo,
>=20
> Du musst darauf achten, dass Tk erst geladen wird, wenn die Threads=20
> erzeugt sind. (Also kein 'use'). Tk darf nur aus dem eigenen Thread=20
> angesprochen werden. Hier ist ein simples Beispiel:
>=20
> use warnings;
> use strict;
>=20
> use threads;
> use threads::shared;
>=20
> my $var =3D1;
> share $var;
> my $data ;
> share $data;
>=20
> my @threads;
>=20
> push @threads, threads->create(\&thread);
> tk_thread();
> $_ -> join for @threads;
>=20
> print "threads joined\n";
>=20
>=20
> sub thread{
> my $counter =3D 0;
> while (1){
> if ($var==1){
> print "thread doing work\n";
> {
> lock $data;
> $data =3D $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 =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 '';
> }
> } );
>=20
> MainLoop();
> }
>=20
>=20
>> Alternativ könnte ich in der Funktion auch immer wieder die=20
>> MessageQueue anstoßen. Wie kann ich das machen?
>>
>=20
>=20
> $mw->update;
>=20
> Grüße, Christoph
>=20


--=20
Schönen Gruß aus dem Bergischen Land
Robert

Re: Perl Tk, Windows, blockierende Funktionen

am 03.07.2007 10:22:28 von KWittrock

"Robert Berghaus" schrieb im Newsbeitrag
news:c1.2bm.35r7W5$LTX@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

am 03.07.2007 15:44:36 von Robert Berghaus

Hallo Christoph

Ch Lamprecht schrieb:
> Robert Berghaus schrieb:
>> Hallo
>>
>> Nach der Eingabe der Daten für FTP wird eine Dateiliste aus einem=20
>> festen Verzeichnis geholt und anschließend maximal 200 Dateien.
>> Bei diesem Vorgang blockiert das Fenster, keinerlei Ausgaben sind mehr=
=20
>> möglich. Ich nehme an, daß ich hier mit einem Thread arbeiten muß=

>> Gibt es dafür Beispiele?
>=20
> Hallo,
>=20
> Du musst darauf achten, dass Tk erst geladen wird, wenn die Threads=20
> erzeugt sind. (Also kein 'use'). Tk darf nur aus dem eigenen Thread=20
> angesprochen werden. Hier ist ein simples Beispiel:
>=20

[Beispiel]
Gibt es für Threads eine lesbare Dokumentation?
In meinem Programm kann ich das so nicht einsetzen, da ich erst in=20
einem Eingabefenster die FTP Zugangsdaten abfrage und dann erst=20
den Import anstoße. Vielleicht kann ich den ja auch als=20
Arbeitsthread beim Start erzeugen und immer wieder für=20
verschiedene Aufgaben benutzen. Zunächst reicht mir aber $mw->update!

>=20
>> Alternativ könnte ich in der Funktion auch immer wieder die=20
>> MessageQueue anstoßen. Wie kann ich das machen?
>>
>=20
>=20
> $mw->update;

Das nehme ich erstmal.

--=20
Schönen Gruß aus dem Bergischen Land
Robert

Re: Perl Tk, Windows, blockierende Funktionen

am 03.07.2007 18:44:15 von Robert Berghaus

Hallo Klaus

K. Wittrock schrieb:
>=20
> "Robert Berghaus" schrieb im Newsbeitrag=20
> news:c1.2bm.35r7W5$LTX@TPA31p-os2.robe-edv.lokal...
>> Hallo
>>
>> Nach der Eingabe der Daten für FTP wird eine Dateiliste aus einem=20
>> festen Verzeichnis geholt und anschließend maximal 200 Dateien.
>> Bei diesem Vorgang blockiert das Fenster, keinerlei Ausgaben sind mehr=
=20
>> möglich. Ich nehme an, daß ich hier mit einem Thread arbeiten muß=

>=20
> Vielleicht geht es auch einfacher. Probier mal die folgenden Möglichk=
eiten:
>=20
Es geht einfacher.

> 1. Möglicherweise beschäftigen die FTP-Transfers deinen Rechner so =
sehr,=20
> dass der Mainloop keine Chance hat, Events zu verarbeiten. Dann solltes=
t=20
> du in hinreichend kurzen Abständen update aufrufen. Wenn die einzelne=
n=20
> Transfers schnell genug sind, genügt ein update nach jedem Transfer.
>=20
Jein, meinen Rechner nicht, wohl aber die SPS.

> 2. Möglicherweise wartet dein Programm in einem Callback auf das Ende=
=20
> der Transfers. Dann könntest du die Transfers in ein nicht blockieren=
des=20
> Toplevel auslagern, so ähnlich wie bei dem Modul zur Anzeige von=20
> Fortschrittsmeldungen, das ich dir gestern geschickt habe. Ein update=20
> nach jedem Transfer kann auch hier nicht schaden.

Ja. Ich versuche mal kurz zu erklären, was dieser Programmteil macht.
Über das Menü (Hotkey Strg-o) wird ein Toplevel Fenster aufgebaut,=20
in welchem die FTP Zugangsdaten abgefragt werden; dann geht es=20
über einen Button weiter und in diesem Callback werden alle 200=20
Dateien von der SPS auf den Rechner geholt. Hier hatte der=20
Mainloop keine Chance, irgendwas zu machen. Jetzt rufe ich bei=20
jeder Datei auch update auf und die Statuszeile wird ihrem Namen=20
gerecht. Da die SPS nach ca. 45 Dateien lange Pause macht (ca.=20
20-30 Sekunden) bringt das in der Pause natürlich nichts, sonst=20
aber wohl.
Auch wenn ich das jetzt auslagere, blockiert ftp->get trotzdem. Ob=20
ich da überhaupt was dran machen kann, weiß ich jetzt noch nicht.

Hast Du bei dem Modul, welches Du mir geschickt hast vielleicht=20
etwas vergessen?

--=20
Vielen Dank und schönen Gruß aus dem Bergischen Land
Robert

Re: Perl Tk, Windows, blockierende Funktionen

am 04.07.2007 00:02:48 von Ch Lamprecht

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@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(@i)});MainL oop