Reputation: 379
I am new to perl and trying out multithreading. I was expecting following program to create all the threads and print "created all the threads" at least after 5 seconds, once executed and all the threads waiting for the input value.
use threads;
my @arr = (1,2,3,4);
foreach (@arr) {
sleep(1);
print "\ncreating...\n";
threads->new(\&echo, $_);
print "\ncreated\n";
}
print "\ncreated all the threads\n";
sleep(200); #wait for the threads to finish
sub echo {
my ($thread) = @_;
print "\nthread($thread) Enter the value:\n";
my $value = <>;
print "\nthread($thread) Got value= $value\n";
}
But I am getting following outout:
creating...
created
thread(1) Enter the value:
creating...
It seems the other 3 threads are not yet created, if I remove the sleep(1) I get sometimes expected result, but with the sleep(1) involved, even waiting for few minutes, I get the above result. What I may be missing? I think it is something basic, but I am not able to figure out.
UPDATE:
The same program works on Linux flawless, what could be the platform specific problem for windows?
UPDATE2:
Following java program on the same lines works just fine on the same box:
import java.io.IOException;
public class MT {
public static void main(String[] args)throws Exception {
for(int i=0;i<4;i++){
Thread.sleep(2000);
new Thread(new Task(i)).start();
}
System.out.println("created all the threads");
Thread.sleep(20000);
}
static class Task implements Runnable{
int i;
public Task(int i) {
super();
this.i = i;
}
@Override
public void run() {
try {
System.out.println("Thread:"+i+" Enter value");
int x= System.in.read();
System.out.println(x);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
I am not sure how perl supports multithreading on windows!
Upvotes: 3
Views: 215
Reputation: 6566
You actually have two different blocking issues:
Consider this test program:
use threads;
$| = 1;
my $thr1 = threads->new(\&echo, 1);
my $thr2 = threads->new(\&print_dots, 2);
sleep 10;
my $thr3 = threads->new(\&echo, 3);
sleep 200;
sub print_dots {
while (1) {
print ".";
sleep 1;
}
}
sub echo {
my ($thread) = @_;
print "\nthread($thread) Enter the value:\n";
sleep 1;
my $value = <>;
print "\nthread($thread) Got value= $value\n";
}
If you do not disable i/o buffering (done by $|=1;
), then you don't get any dots at all. If you disable input buffering, the thread that prints dots is never blocked. However, the second thread that reads from the console is still blocked by the first one.
If you need a true non-blocking read from standard input in Perl on Windows, there are a few potential solutions. Win32::Console
is probably a good place to start. Here is a potentially useful discussion.
Upvotes: 2