【问题标题】:Why are my Perl threads stuck in an infinite loop? (Thread::Queue)为什么我的 Perl 线程陷入无限循环? (线程::队列)
【发布时间】:2015-02-07 16:59:32
【问题描述】:

我正在使用Thread::Queue 将数组推送到队列中并使用线程处理其中的每个元素。下面是我的程序的简化版本,用于演示正在发生的事情。

#!/usr/bin/perl

use strict;
use warnings;

use threads;
use threads::shared;
use Thread::Queue;

# Define queue
my $QUEUE :shared = new Thread::Queue();

# Define values
my @values = qw(string1 string2 string3);

# Enqueue values
$QUEUE->enqueue(@values);

# Get thread limit
my $QUEUE_SIZE   = $QUEUE->pending();
my $thread_limit = $QUEUE_SIZE;

# Create threads
for my $i (1 .. $thread_limit) {
    my $thread = threads->create(\&work);
}

# Join threads
my $i = 0;
for my $thread (threads->list()) {
    $thread->join();
}

print "COMPLETE\n";

# Thread work function
sub work {
    while (my $value = $QUEUE->dequeue()) {
        print "VALUE: $value\n";
        sleep(5);
        print "Finished sleeping\n";
    }
    print "Got out of loop\n";
}

当我运行此代码时,我得到以下输出,然后它就永远挂起:

VALUE: string1
VALUE: string2
VALUE: string3
Finished sleeping
Finished sleeping
Finished sleeping

一旦队列到达终点,while 循环应该中断,脚本应该继续,但它似乎永远不会退出循环。

为什么会卡住?

【问题讨论】:

    标签: multithreading perl queue infinite-loop


    【解决方案1】:

    由于您从未调用过$QUEUE->end(),因此您的线程在dequeue() 上阻塞,等待出现更多条目。

    因此,请确保在最后一次调用 enqueue 之后或加入线程之前调用 $QUEUE->end()

    【讨论】:

    • 谢谢@Hasturkun!我真的只是在您发布答案之前意识到这一点掌心。虽然这只是一个愚蠢的错误,但我会留下这个问题,以防其他一些可怜的 sap 遇到同样的情况。
    • 注意:->end 需要 T::Q 版本 3.01+
    猜你喜欢
    • 2023-03-22
    • 1970-01-01
    • 2015-03-27
    • 1970-01-01
    • 2017-11-08
    • 1970-01-01
    • 2016-04-08
    • 2016-04-11
    • 1970-01-01
    相关资源
    最近更新 更多