multithreading - 当内存使用率变高时 Perl 多线程变慢

标签 multithreading perl memory

大家好~我使用多线程在 Perl 中编写了一个非常简单的代码。代码如下。

#!/bin/perl

use strict;
use threads;
use Benchmark qw(:hireswallclock);

my $starttime;
my $finishtime;
my $timespent;
my $num_of_threads = 1;
my $total_size = 10000000;
my $chunk_size = int($total_size / $num_of_threads);

if($total_size % $num_of_threads){
        $chunk_size++;
}

my @threads = ();

$starttime = Benchmark->new;

for(my $i = 0; $i < $num_of_threads; $i++) {
        my $thread = threads->new(\&search);
        push (@threads, $thread);
}

foreach my $thread (@threads) {
        $thread->join();
}

my $finishtime = Benchmark->new;
$timespent = timediff($finishtime, $starttime);
print "$num_of_threads threads used in ".timestr($timespent)."\nDone!\n";

sub search{
        my $i = 0;
        while($i < $chunk_size){
            $i++;
        }

        return 1;
}

这段代码工作正常,因为当增加线程数时,它会运行得更快。

但是,当在中间添加额外的行时,将创建一个大数组,添加更多线程时代码将运行得更慢。带有附加行的代码如下所示。

#!/bin/perl

use strict;
use threads;
use Benchmark qw(:hireswallclock);

my $starttime;
my $finishtime;
my $timespent;
my $num_of_threads = 1;
my $total_size = 10000000;
my $chunk_size = int($total_size / $num_of_threads);

if($total_size % $num_of_threads){
        $chunk_size++;
}

##########Additional codes##########
print "Preparing data...\n";
$starttime = Benchmark->new;

my @array = ();

for(my $i = 0; $i < $total_size; $i++){
        my $rn = rand();
        push(@array, $rn);
}

$finishtime = Benchmark->new;
$timespent = timediff($finishtime, $starttime);
print "Used ".timestr($timespent)."\n";
######################################

my @threads = ();

$starttime = Benchmark->new;

for(my $i = 0; $i < $num_of_threads; $i++) {
        my $thread = threads->new(\&search);
        push (@threads, $thread);
}

foreach my $thread (@threads) {
        $thread->join();
}

my $finishtime = Benchmark->new;
$timespent = timediff($finishtime, $starttime);
print "$num_of_threads threads used in ".timestr($timespent)."\nDone!\n";

sub search{
        my $i = 0;
        while($i < $chunk_size){
            $i++;
        }

        return 1;
}

我对 Perl 多线程中的这种行为感到很困惑。有谁知道这里可能出了什么问题吗?

谢谢!

最佳答案

您必须记住,当使用 ithreads(解释器线程)时,整个 Perl 解释器,包括代码和内存,都被克隆到新线程中。因此,要克隆的数据越多,所需的时间就越长。有一些方法可以控制克隆的内容;查看 threads perldoc。

您应该尽可能少地执行操作,甚至在生成线程之前不要加载很多模块。

如果您确实有大量数据将被所有线程使用,请将其与threads::shared 共享。然后共享一个数据结构使用shared_clone()。你不能简单地 share() 任何东西,除了一个简单的变量。该共享变量只能包含普通标量或其他共享引用。

如果您要使用或抽取该数据,请使用 Thread::Queue 模块将其设为队列。它会自动共享值并负责锁定。生成工作线程池后,使用 Thread::Semaphore 控制它们。这样他们就不会在你给他们任何事情之前终止。您还可以防止竞争条件。

https://metacpan.org/pod/threads::shared

HTH

关于multithreading - 当内存使用率变高时 Perl 多线程变慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66459184/

相关文章:

c# - 线程卡在 MySqlCommand.ExecuteNonQuery() 中

perl - IO::Prompter - 是否可以禁用历史记录?

perl - 在 Perl 中使用 die 时的退出代码

javascript - V 8's "大对象空间”是否有限制?

c - 当我想将数组写入文件时内存损坏

python - 为什么我的线程比我在 Linux 下的 py3k 多处理中要求我的池的进程多?

c# - 多线程读取和处理大文本文件

java - 如何找出谁在java中创建了一个线程?

python - 带反引号的 perl eval

c - 如何访问动态分配的结构数组中的项?