我是perl的新手并尝试多线程。我期待以下程序创建所有线程并至少在5秒后打印“创建所有线程”,一旦执行并且所有线程都在等待输入值。
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";
}
但是我正在关注:
creating...
created
thread(1) Enter the value:
creating...
似乎还没有创建其他3个线程,如果我移除睡眠(1)我得到有时预期的结果,但是涉及睡眠(1),甚至等待几分钟,我得到上述结果。我可能缺少什么?我认为这是基本的,但我无法弄明白。
更新:
同样的程序在Linux上完美无缺,可能是Windows的平台特定问题?
UPDATE2:
在同一行上的以下java程序可以在同一个盒子上正常工作:
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();
}
}
}
}
我不确定perl如何在windows上支持多线程!
答案 0 :(得分:2)
您实际上有两种不同的阻止问题:
考虑这个测试程序:
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";
}
如果您不禁用i / o缓冲(由$|=1;
完成),那么您根本不会得到任何点。如果禁用输入缓冲,则永远不会阻止打印点的线程。但是,从控制台读取的第二个线程仍然被第一个阻塞。
如果您需要在Windows上使用Perl中的标准输入进行真正的非阻塞读取,那么有一些潜在的解决方案。 Win32::Console
可能是一个很好的起点。 Here is a potentially useful discussion