简体   繁体   English

perl程序中的多线程在Windows上产生意外结果

[英]Multithreading in perl program giving unexpected result on windows

I am new to perl and trying out multithreading. 我是perl的新手并尝试多线程。 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. 我期待以下程序创建所有线程并至少在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";
}

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. 似乎还没有创建其他3个线程,如果我删除了睡眠(1)我得到了有时预期的结果,但是涉及睡眠(1),甚至等待几分钟,我得到了上述结果。 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? 同样的程序在Linux上完美无缺,什么可能是Windows的平台特定问题?

UPDATE2: UPDATE2:

Following java program on the same lines works just fine on the same box: 以下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();
            }
        }
    }
}

I am not sure how perl supports multithreading on windows! 我不确定perl如何在windows上支持多线程!

You actually have two different blocking issues: 你实际上有两个不同的阻塞问题:

  1. I/O buffering on the console (thanks Disco 3 for suggesting this). 在控制台上进行I / O缓冲(感谢Disco 3提供此建议)。
  2. Threads reading from standard input block each other (but not other threads). 从标准输入读取的线程相互阻塞(但不是其他线程)。

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. 如果你不禁用i / o缓冲(由$|=1; ),那么你根本就没有任何点。 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. 如果您需要在Windows上的Perl标准输入中进行真正的非阻塞读取,那么有一些潜在的解决方案。 Win32::Console is probably a good place to start. Win32::Console可能是一个很好的起点。 Here is a potentially useful discussion . 这是一个可能有用的讨论

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM