Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 如何检测线程是否正在运行_Multithreading_Perl - Fatal编程技术网

Multithreading 如何检测线程是否正在运行

Multithreading 如何检测线程是否正在运行,multithreading,perl,Multithreading,Perl,下面是一个简单的代码示例。它只是启动一个线程,等待5秒钟,然后终止它 #!/usr/bin/perl use strict; use warnings; use threads; sub thread_sub { threads->create(sub { sleep 5; # HERE A WHILE ROUTINEs EMULATED BY SLEEP threads->detach(); }); } thread_

下面是一个简单的代码示例。它只是启动一个线程,等待5秒钟,然后终止它

#!/usr/bin/perl
use strict;
use warnings;
use threads;

sub thread_sub
 {
   threads->create(sub
    {
        sleep 5;   # HERE A WHILE ROUTINEs EMULATED BY SLEEP
        threads->detach();
    });
}

thread_sub();
exit;
但结果是:

# ./multithread.pl 
Perl exited with active threads:
        1 running and unjoined
        0 finished and unjoined
        0 running and detached
这是因为它运行线程,但在该线程退出后不等待。
那个么,在退出之前,我如何等待线程完成呢?我知道有
正在运行
,但我不知道如何在我的代码中实现它。显然,报告的代码只是一个示例,用于理解如何实现is_运行。谢谢。

你为什么要这样做?拆开一根线意味着你不在乎它的回归或命运;它将完成并退出,或者在程序即将退出时被终止

如果要等待,请不要
分离
,而是
加入


至于如何使用
正在运行的问题,您需要一个线程对象

use warnings;
use strict;
use feature 'say';
use threads;
$| = 1;

sub thread_sub
{
    my $thr = threads->create(sub
    {
        ## threads->detach();
        sleep 2; say "\tprocessing ..";
        sleep 2; say "\tdone";
    });
    return $thr;
}

my $thr = thread_sub();

while ($thr->is_running) {  # or: while (threads->list)
    sleep 1;
    say "main";
}

$_->join for threads->list;  # instead of detaching

say "done";

顺便说一句,
is\u running
(或
list
)也涵盖了一个分离的线程,上述操作也适用于它。但是这样做没有意义;我只是在讨论你问的方法。

你为什么要这样做?拆开一根线意味着你不在乎它的回归或命运;它将完成并退出,或者在程序即将退出时被终止

如果要等待,请不要
分离
,而是
加入


至于如何使用
正在运行的问题,您需要一个线程对象

use warnings;
use strict;
use feature 'say';
use threads;
$| = 1;

sub thread_sub
{
    my $thr = threads->create(sub
    {
        ## threads->detach();
        sleep 2; say "\tprocessing ..";
        sleep 2; say "\tdone";
    });
    return $thr;
}

my $thr = thread_sub();

while ($thr->is_running) {  # or: while (threads->list)
    sleep 1;
    say "main";
}

$_->join for threads->list;  # instead of detaching

say "done";

顺便说一句,
is\u running
(或
list
)也涵盖了一个分离的线程,上述操作也适用于它。但是这样做没有意义;我只是在讨论您询问的方法。

要等待线程完成,通常使用以下方法:

$thread->join();
$_->join() for threads->list();
因此,要等待所有线程,可以使用以下命令:

$thread->join();
$_->join() for threads->list();
如果这是你要做的,不要拆开线


关于拆离

如果你有火和忘记线程,你可以使用

use threads;
use threads::shared;

my $thread_count :shared = 0;

sub thread_sub {
   { lock $thread_count; ++$thread_count; cond_signal($thread_count); }
   my $thread = async {
      sleep 5;

      { lock $thread_count; --$thread_count; cond_signal($thread_count); }
   };

   $thread->detach();  # Free the small thread object as soon as it completes.
}

thread_sub();

# When it's time to exit:
{ lock($thread_count); cond_wait($thread_count) while $thread_count != 0; }
但这并不能让你比仅仅加入线程获得更多好处,这要简单得多

use threads;

sub thread_sub {
   async {
      sleep 5;
   };
}

thread_sub();

# Periodically:
$_->join() for threads->list(threads::joinable);

# When it's time to exit:
$_->join() for threads->list();
最后,在实践中更常见的做法是创建一个线程池并重用它们,而不是动态创建线程,因为在Perl中创建线程非常昂贵。在这种情况下,分离就更没有意义了

use threads;

use Thread::Queue qw( );  # 3.01+

use constant NUM_WORKERS => 3;

sub process_job { sleep 5 }

my $q = Thread::Queue->new();
for (1..NUM_WORKERS) {
   async {
      while (my $job = $q->dequeue()) {
         process_job($job);
      }
   };
}

$q->enqueue('some_job');

# When it's time to exit:
$q->end();
$_->join() for threads->list();
我没用过,但请仔细看看



顺便说一下,
async{…}
只是说
threads->create(sub{…})
要等待线程完成,通常使用以下方法:

$thread->join();
$_->join() for threads->list();
因此,要等待所有线程,可以使用以下命令:

$thread->join();
$_->join() for threads->list();
如果这是你要做的,不要拆开线


关于拆离

如果你有火和忘记线程,你可以使用

use threads;
use threads::shared;

my $thread_count :shared = 0;

sub thread_sub {
   { lock $thread_count; ++$thread_count; cond_signal($thread_count); }
   my $thread = async {
      sleep 5;

      { lock $thread_count; --$thread_count; cond_signal($thread_count); }
   };

   $thread->detach();  # Free the small thread object as soon as it completes.
}

thread_sub();

# When it's time to exit:
{ lock($thread_count); cond_wait($thread_count) while $thread_count != 0; }
但这并不能让你比仅仅加入线程获得更多好处,这要简单得多

use threads;

sub thread_sub {
   async {
      sleep 5;
   };
}

thread_sub();

# Periodically:
$_->join() for threads->list(threads::joinable);

# When it's time to exit:
$_->join() for threads->list();
最后,在实践中更常见的做法是创建一个线程池并重用它们,而不是动态创建线程,因为在Perl中创建线程非常昂贵。在这种情况下,分离就更没有意义了

use threads;

use Thread::Queue qw( );  # 3.01+

use constant NUM_WORKERS => 3;

sub process_job { sleep 5 }

my $q = Thread::Queue->new();
for (1..NUM_WORKERS) {
   async {
      while (my $job = $q->dequeue()) {
         process_job($job);
      }
   };
}

$q->enqueue('some_job');

# When it's time to exit:
$q->end();
$_->join() for threads->list();
我没用过,但请仔细看看



顺便说一下,
async{…}
只是说
threads->create(sub{…})

@ikegami啊,是的!非常感谢。(需要弄清楚如何“启动并忘记线程”)据我所知,当涉及到“启动并忘记线程”时,答案是“几乎永远不会”——如果程序在线程之前退出,则存在“免费”的争用条件。即使事实并非如此,perl线程模型也是重量级的,而不是轻量级的,因此无论如何也不适合于“火与忘”的事情。@Sobrique Right。。。我认为ikegami这个短语指的是线程模型或库。实际上是关于他发布的方法,实现了这一点。另一个伟大的作品:)。在Perl中,我不知何故不在生产中使用线程(我在C++中使用)。我很少有需要池的长时间运行的作业,或者对于IPC来说过于繁重的数据交换,我只是不明白为什么我会使用它们——我使用fork。还在等待一个问题,线程将是一个更好的解决方案。@ikegami啊,是的!非常感谢。(需要弄清楚如何“启动并忘记线程”)据我所知,当涉及到“启动并忘记线程”时,答案是“几乎永远不会”——如果程序在线程之前退出,则存在“免费”的争用条件。即使事实并非如此,perl线程模型也是重量级的,而不是轻量级的,因此无论如何也不适合于“火与忘”的事情。@Sobrique Right。。。我认为ikegami这个短语指的是线程模型或库。实际上是关于他发布的方法,实现了这一点。另一个伟大的作品:)。在Perl中,我不知何故不在生产中使用线程(我在C++中使用)。我很少有需要池的长时间运行的作业,或者对于IPC来说过于繁重的数据交换,我只是不明白为什么我会使用它们——我使用fork。仍然在等待一个问题,线程将是一个更好的解决方案。谢谢你,顺便说一句,关于线程池的创建(最后一个代码),我得到了:无法通过位于./multi.pl第24行的包“thread::Queue”找到对象方法“end”。更新你的
thread::Queue
,你正在运行一个旧版本。@Lucas Rey,你需要3.01或更高版本。//您可能希望查看Thread::Pool,而不是编写自己的池。(添加了提及和答案链接。)谢谢你,顺便说一句,我得到了线程池创建(最后一个代码):无法通过位于./multi.pl第24行的包“thread::Queue”找到对象方法“end”。更新你的
thread::Queue
,你正在运行一个旧版本。@Lucas Rey,你需要3.01或更高版本。//您可能希望查看Thread::Pool,而不是编写自己的池。(添加了答案的提及和链接。)