简体   繁体   中英

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)

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

But in perl, when I create itself it has started. For example

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

But I want to create 4 thread. 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 ?

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,

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. It doesn't process the remaining 6 items in the queue.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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