in reply to Re^3: How to deal with a forked proces that is waiting for user input?
in thread How to deal with a forked proces that is waiting for user input?
Here is my latest 2 implementations. They both allow me to detach the thread without a hang. Only the first one gets back the information even in the case of it waiting for user input. But I am not sure if either is exactly thread safe, and I am not sure I am using the thread queue as you intended. But this was the way I could get it working.
Implementation 1:
my $queue = new Thread::Queue; my $command = 'diskpart'; my $status = _timedCommand($command, 90); if ($status eq 'TIMEOUT') { print "\n=======TIMEOUT==========\n"; } my @ans; while (my $ref = $queue->dequeue_nb()) { if (ref($ref) =~ m/ARRAY/i) { push(@ans, @$ref); } else { push(@ans, $ref); } } print "@ans\n"; sub _timedCommand { my ($command, $time) = @_; my $pid :shared; my @tmp :shared; my $thr = async { $pid = open my $fh, "$command |" or die "$!"; push @tmp, $_ while <$fh>; $fh->close(); }; while ($thr->is_running() and $time > 0) { sleep(1); $time--; } if ($thr->is_joinable()) { $thr->detach(); $queue->enqueue(\@tmp); return 'OK'; } else { $thr->detach; kill 3, $pid; $queue->enqueue(\@tmp); return 'TIMEOUT'; } }
Implementation 2:
my $queue = new Thread::Queue; my $command = 'diskpart'; my $status = _timedCommand($command, 90); if ($status eq 'TIMEOUT') { print "\n=======TIMEOUT==========\n"; } my @ans; while (my $ref = $queue->dequeue_nb()) { if (ref($ref) =~ m/ARRAY/i) { push(@ans, @$ref); } else { push(@ans, $ref); } } print "@ans\n"; sub _timedCommand { my ($command, $time) = @_; my $pid :shared; my $thr = async { $pid = open my $fh, "$command |" or die "$!"; my @tmp :shared; push @tmp, $_ while <$fh>; $queue->enqueue(\@tmp); $fh->close(); }; while ($thr->is_running() and $time > 0) { sleep(1); $time--; } if ($thr->is_joinable()) { $thr->detach(); return 'OK'; } else { $thr->detach; kill 3, $pid; return 'TIMEOUT'; } }
In the second implementation I am seeing some wonky stuff when running the diskpart command, at times it @ans is populated and it prints out information, at other times it is not and doesn't. I have to assume its a timing issue, but I am not sure where it would be. For a dir command it works as expected.
Output from Implementation 1:
C:\Sandbox>perl ForkProcessTimeout.pl =======TIMEOUT========== Microsoft DiskPart version 5.1.3565 Copyright (C) 1999-2003 Microsoft Corporation. On computer: USITPAPADGD1C DISKPART>
Output from Implementation 2:
The output is inconsistent:
C:\Sandbox>perl ForkProcessTimeout.pl =======TIMEOUT========== Microsoft DiskPart version 5.1.3565 Copyright (C) 1999-2003 Microsoft Corporation. On computer: USITPAPADGD1C DISKPART> C:\Sandbox>perl ForkProcessTimeout.pl =======TIMEOUT========== C:\Sandbox>perl ForkProcessTimeout.pl =======TIMEOUT========== Microsoft DiskPart version 5.1.3565 Copyright (C) 1999-2003 Microsoft Corporation. On computer: USITPAPADGD1C DISKPART>
I think implementation 2 is the way I need to go for it to be threadsafe, but I don't get the consistency in output. Also when I run implementation 2 in the debugger it seems to consistently include the output.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^5: How to deal with a forked proces that is waiting for user input?
by BrowserUk (Patriarch) on Oct 22, 2008 at 16:12 UTC | |
by gepapa (Acolyte) on Oct 22, 2008 at 16:34 UTC | |
by BrowserUk (Patriarch) on Oct 22, 2008 at 17:34 UTC | |
by gepapa (Acolyte) on Oct 22, 2008 at 18:00 UTC | |
by BrowserUk (Patriarch) on Oct 22, 2008 at 18:13 UTC | |
|