简体   繁体   English

如何在perl中按需启动线程?

[英]How to Start thread only on demand in perl?

In c#, we can create thread and start thread only on need like following (if I am correct) 在c#中,我们可以创建线程并仅在需要时启动线程如下(如果我是正确的)

Thread th=new thread("function");
th.start()

But in perl, when I create itself it has started. 但是在perl中,当我创建自己时,它已经开始了。 For example 例如

$thread1=thread->create("function");

But I want to create 4 thread. 但我想创建4个线程。 I should start only on need. 我应该只根据需要开始。 And I've to check whether it's running or not? 我要检查它是否正在运行? if thread is not running, then I've to start the same thread by passing different parameter. 如果线程没有运行,那么我将通过传递不同的参数来启动相同的线程。 How to do that in perl ? 如何在perl中做到这一点?

Multiple jobs can be sent into the queue, and they are waiting for their turn to be passed to the worker. 可以将多个作业发送到队列中,并等待轮到他们传递给工作人员。

use strict;
use warnings;
use threads;
use Thread::Queue;

my $no_of_workers = 4;
my $q = Thread::Queue->new();
# Worker thread
my @thr = map {

  my $t = threads->create(sub{

    # Thread will loop until no more work
    while (defined(my $item = $q->dequeue())) {
        # Do work on $item
        print "$item\n";
    }
  });

  {queue => $q, thread => $t, id => $_};

} 1 .. $no_of_workers;


# Send work to each thread
$_->{queue}->enqueue("Job for thread $_->{id}") for @thr;

for (@thr) {
  # Signal that there is no more work to be sent
  # $_->{queue}->end();

  # similar to $queue->end() for older perl
  $_->{queue}->enqueue(undef) for @thr;

  # wait for threads to finish
  $_->{thread}->join();
}

Assigning jobs 0..19 in circular way to workers, 将工作0..19以循环方式分配给工人,

for my $i (0 .. 19) {
  my $t = $thr[$i % @thr]; # $i % @thr => 0,1,2,3, 0,1,2,3, ..
  $t->{queue}->enqueue("Job for thread $t->{id}");
}

You don't want a queue for each thread! 你不希望每个线程都有一个队列! You'll end up with idle threads even if work's available. 即使工作可用,你也会得到空闲的线程。

use strict;
use warnings;

use threads;

use Thread::Queue 3.01 qw( );

use constant NUM_WORKERS => 4;

sub worker {
   my ($job) = @_;
   print("Job: $job\n");
   sleep(rand(4));  # Pretending to do $job
}

{
   my $q = Thread::Queue->new();

   for (1..NUM_WORKERS) {
      async {
         while (defined(my $item = $q->dequeue())) {
            worker($item);
         }
      };
   }

   # Give the workers work to do.
   $q->enqueue($_) for 1..14;

   # When you're done adding, wait for the workers to finish.
   $q->end();
   $_->join() for threads->list;
}

This code only does 4 threads, and then stops. 此代码仅执行4个线程,然后停止。 It doesn't process the remaining 6 items in the queue. 它不处理队列中剩余的6个项目。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM