Schrift
[thread]12595[/thread]

Win32 - Pipe erzeugung funktioniert nicht

Leser: 2


<< >> 4 Einträge, 1 Seite
Snicker
 2008-10-07 14:18
#115243 #115243
User since
2008-08-09
25 Artikel
BenutzerIn
[default_avatar]
Hallo,
ich habe einen Prozess, den ich kontrolliert forken will. Das Forken funktioniert auch einwandfrei. Das Problem ist die Steuerung der geforkten Prozesse. Hierzu möchte ich mittels Pipes das ganze kontrollieren. Da ich als Betriebssystem Windows XP benutze muss ich Win32:Pipe verwenden.

Das Problem liegt darin, dass kein einziger Pipe erzeugt wird. Die fork-Prozesse werden alle erfolgreich gestartet, aber es wird kein Pipe erzeugt. Erhalte auch über den die Befehl keine Meldung, dass die Pipeerzeugung nicht funktioniert hat.

Im Konsolenfenster erhalte ich die Meldung:
bin ein Childprozess
bin ein Childprozess
bin ein Childprozess
bin ein Childprozess

sorry, i cannot find the pipe: My Pipe Name 0 at D:\.....\Open65.pl line 482






Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
use Win32::Pipe;

while ($q < ($einstellungen_para_wert[12] * $einstellungen_para_wert[13])){
    $pid = fork() ;
    unless (defined $pid) {
        die "Could not fork $!";
    }
    #---------------------------------------------------------------------------
    #   Hier beginnt der Child-Prozess
    #---------------------------------------------------------------------------
    elsif ($pid < 0){
        print "bin ein Childprozess\n",
        $Pipe = new Win32::Pipe("My Pipe Name $q") or die "sorry, i cannot creat a pipe";
        print "Pipe wurde erfolgreich erschaffen";
        $Result = $Pipe->Connect() or die "sorry, i cannot connect to the pipe";
        $Result = $Pipe->Write("Howdy! This is cool!") or die "sorry, i cannot write in the pipe";
        $Pipe->Disconnect() or die "sorry, i cannot disconnect to the pipe";
        
        #Hier läuft das Programm mittels dem [i]system()[/i] Befehl 
        
        $Result = $Pipe->Connect();
        $Result = $Pipe->Write("Now i´m ready!");
        $Pipe->Disconnect();

        exit(0);
    }
    #---------------------------------------------------------------------------
    #   Hier beginnt der Parent-Prozess
    #---------------------------------------------------------------------------
    else{
        while ($k1 == $einstellungen_para_wert[12] ){
            for ($op = ($q - ($k1 - 1)); $op < ($q ); $op++){
                $Pipe = new Win32::Pipe("\\\\server\\pipe\\My Pipe Name $op") or die "sorry, i cannot find the  pipe: My Pipe Name $op"; #line 482
                $Result = $Pipe->Connect();
                $Data = $Pipe->Read();
                $Pipe->Disconnect();
                if ($Data eq "Now i´m ready!"){
                    $k1--;
                    $Data->Close();
                    wait;
                }
            }
            Win32::Sleep 100;   #Programm pausiert 0,1 Sek. sonst beansprucht Perl die frei werdenen Ressourcen.
        }
        $k1++;
        $q++;
    }
}
Taulmarill
 2008-10-07 19:07
#115249 #115249
User since
2004-02-19
1750 Artikel
BenutzerIn

user image
Hm, evtl. habe ich nur irgend etwas an deinem Script nicht verstanden, aber für mich sieht es so aus, als ob du eine Pipe mit dem Namen "My Pipe Name $q" erzeugst und dann versuchst nach "My Pipe Name $op" zu verbinden. Dabei ist aber nicht sicher gestellt, dass $q == $op ist. So wie das ganze aussieht bin ich mir sogar ziemlich sicher, dass $q != $op. Da das Programm nach dem ersten fehlgeschlagenen Versuch sofort mit die beendet wird, kommt es nie zu einer Verbindung.
$_=unpack"B*",~pack"H*",$_ and y&1|0& |#&&print"$_\n"for@.=qw BFA2F7C39139F45F78
0A28104594444504400 0A2F107D54447DE7800 0A2110453444450500 73CF1045138445F4800 0
F3EF2044E3D17DE 8A08A0451412411 F3CF207DF41C79E 820A20451412414 83E93C4513D17D2B
murphy
 2008-10-07 19:28
#115250 #115250
User since
2004-07-19
1776 Artikel
HausmeisterIn
[Homepage]
user image
Sollte man in diesem einfachen Fall nicht eigentlich auch mit my $pid = open my $pipe, '-|'; auskommen?

Zum Beispiel so:
Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
use 5.010;
use strict;
use warnings;

use Symbol qw/gensym/;

sub spawn_worker(&) {
  my ($thunk) = @_;
  
  my $pipe = gensym;
  my $pid = open $pipe, '-|';
  die "Unable to create worker: $!" unless (defined($pid));
  
  if ($pid == 0) {
    $thunk->($pipe);
    exit 0;
  }
  else {
    return ($pid, $pipe);
  }
}

sub collect_work($*) {
  my ($pid, $pipe) = @_;
  my $_;
  
  print "$pid >> $_" while (<$pipe>);
  die "Unable to read from worker $pid: $!" if ($!);
  
  close $pipe or die "Unable to close worker $pid: $!";
}

my %workers = ();
for my $idx (0..10) {
  my ($pid, $pipe) = spawn_worker {
    print "Hello, I'm worker $idx\n";
  };
  
  $workers{$pid} = $pipe;
}

while (my ($pid, $pipe) = each %workers) {
  collect_work $pid, $pipe;
}
When C++ is your hammer, every problem looks like your thumb.
Snicker
 2008-10-07 19:54
#115251 #115251
User since
2008-08-09
25 Artikel
BenutzerIn
[default_avatar]
Taulmarill+2008-10-07 17:07:24--
Hm, evtl. habe ich nur irgend etwas an deinem Script nicht verstanden, aber für mich sieht es so aus, als ob du eine Pipe mit dem Namen "My Pipe Name $q" erzeugst und dann versuchst nach "My Pipe Name $op" zu verbinden. Dabei ist aber nicht sicher gestellt, dass $q == $op ist. So wie das ganze aussieht bin ich mir sogar ziemlich sicher, dass $q != $op. Da das Programm nach dem ersten fehlgeschlagenen Versuch sofort mit die beendet wird, kommt es nie zu einer Verbindung.


das Problem liegt nicht beim $q != $op, da $op ==$q. Hab das nochmal nachgeprüft.
Das erstaunlich ist, dass die Berechnungen im Fork-Prozess nicht ausgeführt werden. Sobald ich aber satt
Code (perl): (dl )
$Pipe = new Win32::Pipe("\\\\server\\pipe\\My Pipe Name $op")

Code (perl): (dl )
$Pipe = new Win32::Pipe("\\\\.\\pipe\\My Pipe Name $op")
schreibe, werden meine Berechnungen in jedem Forkprozess gestartet. Eigentlich dürfte es keinen Unterschied geben.

Versuche ich nun im fork-prozess den pipe auszulesen, dann erhalte ich ebenfalls die Fehlermeldung, dass das Lesen meines "My Pipe Name 0" nicht funktioniert hat. Irgendwie scheine ich wohl nicht in der Lage zu sein, meine Pipes starten zu können bzw. nicht lesen zu können, obwohl die Namen übereinstimmen.

@$q!=$op:
in der Hinsicht hast teilweise Recht. Mein Intervall wurde von mir um 1 zu klein gewählt. Statt 0 ... 3 hat er bisher 0 ... 2 abgesucht. Habe es jetzt korrigiert.
<< >> 4 Einträge, 1 Seite



View all threads created 2008-10-07 14:18.