multithreading - Thread::Queue 如何在线程之间平均分配作业
问题描述
这是代码:
#!/usr/bin/perl
use strict;
use warnings;
use threads;
use Thread::Queue;
my $queue = Thread::Queue->new();
sub run_queries {
my $n = shift;
print "$n\n-------------\n";
# $queue->dequeue_nb() does the same
while (defined(my $text = $queue->dequeue())) {
print "$text\n";
}
}
my @threads;
push(@threads, threads->create(\&run_queries, 1));
push(@threads, threads->create(\&run_queries, 2));
push(@threads, threads->create(\&run_queries, 3));
push(@threads, threads->create(\&run_queries, 4));
for (my $i = 0; $i < 12; $i++)
{
$queue->enqueue($i);
}
$queue->end();
foreach (@threads) {
$_->join();
}
输出:
1
-------------
2
-------------
3
-------------
4
-------------
0
1
2
3
... all the items here
我预计输出将在线程之间均匀分布,一旦一个线程从队列中取出项目,第二个线程将激活并开始处理下一个项目。
但实际上我们看到一个线程正在处理所有事情,而其他线程则处于空闲状态。
我需要做什么才能在线程之间平均分配作业?
解决方案
是什么让你认为这是一个线程?
改变
print "$text\n";
至
print "[$n] $text\n";
或者
print "[" . threads->tid . "] $text\n";
样本输出:
1
-------------
2
-------------
3
-------------
4
-------------
[2] 0
[1] 1
[2] 2
[4] 3
[3] 4
[3] 5
[1] 6
[1] 7
[2] 8
[1] 9
[2] 10
[4] 11
您可能还想尝试使用
use Time::HiRes qw( sleep );
print "[" . threads->tid . "] START $text\n";
sleep(rand()+1); # [1,2) seconds
print "[" . threads->tid . "] END $text\n";
# After the loop.
print "[" . threads->tid . "] EXIT\n";
样本输出:
[2] START 0 \
[3] START 1 \ All the workers start right off the bat.
[4] START 2 /
[1] START 3 /
[1] END 3 \ As soon as a worker finishes one job,
[1] START 4 / it starts the next available job.
[4] END 2
[4] START 5
[3] END 1
[3] START 6
[2] END 0
[2] START 7
[1] END 4
[1] START 8
[4] END 5
[4] START 9
[1] END 8
[1] START 10
[2] END 7
[2] START 11
[3] END 6 \ There are no jobs left. Because ->end was called, it exits.
[3] EXIT / Otherwise, it would block until ->enqueue or ->end is called.
[4] END 9
[4] EXIT
[2] END 11
[2] EXIT
[1] END 10
[1] EXIT
推荐阅读
- mysql - 尝试在 Woocommerce 中编辑订单详细信息页面
- python - Python 3.5 pip 9 AttributeError:“NoneType”对象没有属性“字节”
- spring - Spring Boot + Thymeleaf Security 无法识别
- typescript - 命名空间声明
- android - 在 Android 免安装应用中下载文件
- java - 可以将 html img 添加到 JBUTTON 吗?
- django - 脸书认证错误。将 ngrok 用于 https 后,网址不安全
- python - 类实例方法调用和@property 访问委托
- python - 如何在两个 URL 之间使用 Python 代理文件
- python - Django-将多个模型对象保存到数据库