3

edit: did some sorting and more explaining after comments

I programmed a small client-server application, and then added logging which at first worked and now gets my program to freeze.

The server starts some child processes, which communicate via sockets with the server.

My program is started in a Cygwin shell, and to complicate things further I can't use CPAN to install new modules in my environment. IO::Tee and Tee are not installed.

For logging I used

SERVER

open (STDOUT, "|/bin/tee  $logfile");
Init();

which at first seemed to work fine. This one is called as one of the first lines in the Server, apart from subfunctions

So my Server does some subroutines

SERVER::Init

OpenSockets();
CreateMatrix();
PrintMatrix();
StartClients();

My server does some forks and calculations and then ends the child processes; then there is some more calculations.

Later on I start my clients with

SERVER::StartClients

foreach my $server ( @servers ) {
  foreach my $feature( @features ) {

    if ( $hasserverlicense{$server}{$feature} ) {
      PrintTimed("Client started for $feature \@ $server");
      system("perl w:/lma/client.pl $server $feature &");
    }
  }
}

tee and STDOUT work till StartClients, wich basically is the code above and the one which gets stuck. CreateMatrix is a Sub where forking is done but all forking stuff Ends there too.

SERVER::CreateMatrix

my $pipes = IO::Select->new();

foreach my $server (@servers) {
    foreach my $feature (@features) {
        # FORKING HAPPENS HERE
                    my $pipe = IO::Pipe->new;
        my $pid;

        if ( $pid = fork ) {
                #PARENT
            #save pipe
            $pipe->reader;
            $pipes->add($pipe);
        }
        elsif ( defined $pid ) {
                            #CHILDREN
            #set pipe
            $pipe->writer;
            select $pipe;
            ....  backticks command and Evaluation here ....
            print ("$ans");
            exit;
        }
    }
}
#THIS IS PARENT PROCESS
while($pipes->count()){
    my @pipes = $pipes->can_read();
    foreach my $pipe (@pipes) {
                    ... processing of read from pipe ...
        $pipes->remove($pipe);
    }
}
    #CHILDS EXIT AFTER THIS, NO MORE FORKING IS DONE
    #AFTER THIS, ONLY BACKTICKS OPERATIONS IN OTHER ROUTINES

So my childs shouldnt mess up my STDOUT there, anyhow the Server continues and still prints. Also, Clients do not use STDOUT

CLIENT

while(1){

    ... backticks op, editing and generating $ans ...

# Opening Connection and sending answer
$socket = new IO::Socket::INET (.....) die unless $socket;
$socket->send("$ans");
$socket->shutdown(1);
$socket->close();
}

So, whats the Problem? Server does fine until SERVER::StartClients In normal cases, about eight clients should be started. When enabling the tee, two to four clients are started and then nothing more happens: everything gets stuck and the Perl process does not respond any more. No more Output is written to the console. If i comment out

#open (STDOUT, "|/bin/tee  $logfile");

everything is working again fine, all Clients are started and Server does everything he should do.

Community
  • 1
  • 1
chenino
  • 454
  • 2
  • 7
  • 19
  • 3
    Why can't you use CPAN? Is there no internet, do you not have sufficient rights to run it or are you simply not allowed by a policy? For two of those there is a solution. Check [local::lib](http://p3rl.org/local::lib) and [minicpan](https://metacpan.org/pod/distribution/CPAN-Mini/bin/minicpan) – simbabque May 21 '15 at 09:39
  • Well, at least the first two of this match. About the 3rd one, i might get libs in my program as long as i don't install them into the perl enviroment. But even this is not advised, best way would be to fix this. – chenino May 21 '15 at 09:47
  • 3
    You could fat-pack them and ship them with your product. See https://metacpan.org/pod/App::FatPacker. Though I know that doesn't fix your problem, I thought it might be worth giving a shot since you put emphasys on the fact that you cannot install Tie or IO::Tee. :) – simbabque May 21 '15 at 09:48
  • well, mostly because i know the first answer People would give me would be "install packet::x from cpan", so i wanted to clean this out in before :) but i think your hints on this may help me for upcoming projects, so i am grateful for them too ! – chenino May 21 '15 at 10:03
  • 2
    @chenino: It is very easy to install CPAN modules anywhere unless you are prohibited by company policy. The `@INC` array has the current directory `.` as its last entry by default. Both `Tee` and `IO::Tee` are pure Perl, so you can just copy `Tee.pm` and `IO/Tee.pm` into place and it will work – Borodin May 21 '15 at 12:10
  • 1
    Can we see more of your code please? It isn't clear what processes are starting what children, and where the piped open is being executed. I suspect the problem is to do with repeated piped opens, as each new child process will acquire and write to a clone of the parent's STDOUT, which by now may be a pipe to a previous copy of `/bin/tee` – Borodin May 21 '15 at 12:21
  • @Borodin The Client Processes do not use print at all, they just communicate over Sockets. If you relate to the forking Thing, this happens before the Client spawn and afterwards STDOUT and Tee still work. But i may copy some more code to this one – chenino May 22 '15 at 09:54
  • @chenino: Okay, thank you. Can you show where the call to open `|/bin/tee` fits into that framework, and describe better which processes are servers, clients, parents, and children? – Borodin May 22 '15 at 10:37
  • @Borodin will do another edit on the main thread – chenino May 22 '15 at 10:47
  • @chenino: Ah, so there is *one* server, and it is the parent, and multiple clients, and they are the children? And there is only *one* cal to open `|/bin/tee` anywhere? Your willingness to help us to answer you by supplying additional information has earned you my respect and an upvote: thank you.) – Borodin May 22 '15 at 11:05
  • @Borodin : you already got my respect for some times you helped me :) You almost got it. Before my Server starts, it does some calculations with forks. The Clients will be started from my Server, but they are not the forks. I do the forking to get to know, wich children i have to start. So in the right order, it is Server is parent, forks and calculates in children who write back to Server, Server Ends children and forking stuff, calculates some more and spawns Clients afterwards. So forking should not be relevant to the issue, as far as i see – chenino May 22 '15 at 11:09

0 Answers0