[英]Give Threads their own spawned Expect: Unsupported ref type: GLOB
I have a bunch of devices I have to logon to and run a few commands on them. 我有一堆设备必须登录并在其中运行一些命令。 As it takes time and there are a bunch of them I want to parallelise the task, do a few of them at the same time.
由于需要时间,并且有很多我想并行执行任务,因此请同时执行其中的一些任务。 I've done it with
Net::Telnet
however I have to use Expect.pm
now. 我已经用
Net::Telnet
完成了,但是我现在必须使用Expect.pm
。
In my main thread I fill up the @FW
array with hashrefs called \\%host
thusly: 在我的主线程中,我用称为
\\%host
的@FW
填充了@FW
数组:
my $EXPECT = new Expect();
$EXPECT->spawn("ssh $username\@$ip");
$host{'expect'} = $EXPECT;
push(@FW, \%host);
Then I do a thread pool/queue i nicked from perlmonks which I've used for a few other things so I know that approach does work however I'm getting the error (check my comment in the code below) 然后我做了一个线程池/队列,这个线程池/队列是我从perlmonks昵称的,我已经将其用于其他一些事情,所以我知道该方法确实有效,但是我遇到了错误(请在下面的代码中查看我的评论)
sub getWorkItems {
my $host = pop(@FW);
return $host ? $host : undef;
}
our $THREADS = 3;
my $Qwork = new Thread::Queue;
my $Qresults = new Thread::Queue;
my @pool = map {
threads->create(\&worker, $Qwork, $Qresults)
} 1 .. $THREADS;
while (my $workItem = getWorkItems()) { # ERROR HERE: Unsupported ref type: GLOB
$Qwork->enqueue($workItem);
}
$Qwork->enqueue((undef) x $THREADS);
sub worker {
my $tid = threads->tid;
my ($Qwork, $Qresults) = @_;
while (my $host = $Qwork->dequeue()) {
backup($host->{'expect'}, $host->{'hostname'}, $host->{'ip'}, $host->{'username'}, $host->{'password'});
}
$Qresults->enqueue(undef); ## Signal this thread is finished
}
for (1 .. $THREADS) {
while (my $result = $Qresults->dequeue()) {
print "T$_ $result", "\n";
}
}
foreach (@pool) {
$_->join();
}
I've read on CPAN that I have to give each thread its own spawned expect, but what am I doing wrong? 我在CPAN上阅读过,我必须给每个线程一个自己产生的期望,但是我在做什么错呢? I'm trying to pass the object via the same hash along with the other arguments heres how the
backup
sub begins: 我试图通过相同的哈希值以及其他参数来传递对象,以下是
backup
子程序的开始方式:
sub backup {
my ($EXPECT, $hostname, $ip, $username, $password) = @_;
print "$EXPECT, $hostname, $ip, $username, $password\n";
my $auth = $EXPECT->expect(3, -re => "authenticity of host");
(I don't see that print statement) (我看不到该打印声明)
Again, this question is not about my use of Expect (that works), it's about how to use Expect in threads. 再次,这个问题不是关于我对Expect(有效)的使用,而是关于如何在线程中使用Expect。
Thread::Queue
uses threads::shared
under the hood, and threads::shared
does not support all Perl data types. Thread::Queue
使用threads::shared
,而threads::shared
不支持所有Perl数据类型。 Especially it looks like GLOBs are not supported. 特别是看起来不支持GLOB。
use threads;
use threads::shared;
my $foo :shared;
for my $val (1, "foo", qr{regexp}, ["array"], {"ha"=>"sh"}, \*STDOUT, sub { }) {
eval { $foo = shared_clone($val) };
warn "Setting to $val failed: $@" if $@;
}
With a threaded perl 5.18.1 I get: 使用线程Perl 5.18.1,我得到:
Setting to (?^:regexp) failed: Unsupported ref type: REGEXP at shared.pl line 8.
Setting to GLOB(0x80184e798) failed: Unsupported ref type: GLOB at shared.pl line 8.
Setting to CODE(0x801aa78e8) failed: Unsupported ref type: CODE at shared.pl line 8.
I don't think you can do anything about it, other than not using threads, but instead using event-based mechanisms ( Event.pm
, AnyEvent
, POE
...) or even think about using traditional pipe
+ fork
. 除了不使用线程,我不认为您可以做任何事情,而是使用基于事件的机制(
Event.pm
, AnyEvent
, POE
...),甚至考虑使用传统的pipe
+ fork
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.