Perl与线程共享文件句柄 [英] perl share filehandle with threads
问题描述
我在下面的网上找到了代码,看来程序控制循环的方式是检查共享变量$ TERM是否为0.我可以在线程之间共享一个文件句柄吗,每个线程都处理一个文件的一行并在文件到达最后一行时循环结束?
I've found the code below online, it seems the way the program control the loop is to check the shared variable $TERM is 0 or not. Can I share a filehandle between threads, that every thread deal with one line of a file and loop ends when the file reaches the last line?
#!/usr/bin/perl
use strict;
use warnings;
use threads 1.39;
use threads::shared;
use Thread::Queue;
### Global Variables ###
# Maximum working threads
my $MAX_THREADS = 10;
# Flag to inform all threads that application is terminating
my $TERM :shared = 0;
# Threads add their ID to this queue when they are ready for work
# Also, when app terminates a -1 is added to this queue
my $IDLE_QUEUE = Thread::Queue->new();
### Signal Handling ###
# Gracefully terminate application on ^C or command line 'kill'
$SIG{'INT'} = $SIG{'TERM'} =
sub {
print(">>> Terminating <<<\n");
$TERM = 1;
# Add -1 to head of idle queue to signal termination
$IDLE_QUEUE->insert(0, -1);
};
### Main Processing Section ###
MAIN:
{
### INITIALIZE ###
# Thread work queues referenced by thread ID
my %work_queues;
# Create the thread pool
for (1..$MAX_THREADS) {
# Create a work queue for a thread
my $work_q = Thread::Queue->new();
# Create the thread, and give it the work queue
my $thr = threads->create('worker', $work_q);
# Remember the thread's work queue
$work_queues{$thr->tid()} = $work_q;
}
### DO WORK ###
# Manage the thread pool until signalled to terminate
while (! $TERM) {
# Wait for an available thread
my $tid = $IDLE_QUEUE->dequeue();
# Check for termination condition
last if ($tid < 0);
# Give the thread some work to do
my $work = 5 + int(rand(10));
$work_queues{$tid}->enqueue($work);
}
### CLEANING UP ###
# Signal all threads that there is no more work
$work_queues{$_}->enqueue(-1) foreach keys(%work_queues);
# Wait for all the threads to finish
$_->join() foreach threads->list();
}
print("Done\n");
exit(0);
### Thread Entry Point Subroutines ###
# A worker thread
sub worker
{
my ($work_q) = @_;
# This thread's ID
my $tid = threads->tid();
# Work loop
do {
# Indicate that were are ready to do work
printf("Idle -> %2d\n", $tid);
$IDLE_QUEUE->enqueue($tid);
# Wait for work from the queue
my $work = $work_q->dequeue();
# If no more work, exit
last if ($work < 0);
# Do some work while monitoring $TERM
printf(" %2d <- Working\n", $tid);
while (($work > 0) && ! $TERM) {
$work -= sleep($work);
}
# Loop back to idle state if not told to terminate
} while (! $TERM);
# All done
printf("Finished -> %2d\n", $tid);
}
推荐答案
我可以在线程之间共享文件句柄
Can I share a filehandle between threads
否.
每个线程处理文件的一行并在文件到达最后一行时结束循环?
that every thread deal with one line of a file and loop ends when the file reaches the last line?
是的.只需将文件中的行而不是数字输入工作线程即可.
Yes. Just feed the lines from the file instead of numbers to the worker threads.
顺便说一句,您不需要11个队列.您只需要一个:
By the way, you don't need 11 queues to do that. You just need one:
#!/usr/bin/perl
use strict;
use warnings;
use threads 1.39;
use threads::shared;
use Thread::Queue qw( );
# Maximum working threads
my $NUM_WORKERS = 10;
# Flag to inform all threads that application is terminating
my $TERM :shared = 0;
my $request_q = Thread::Queue->new();
$SIG{INT} = $SIG{TERM} = \&signal_handler;
exit(main());
sub signal_handler {
print(">>> Terminating <<<\n");
$TERM = 1;
}
sub main {
my @threads;
push @threads, threads->create(\&worker)
for 1..$NUM_WORKERS;
while (!$TERM && defined(my $job = <>)) {
chomp($job);
$request_q->enqueue($job);
}
# Signal to threads that there is no more work.
$q->enqueue(undef) for 1..$NUM_WORKERS;
# Wait for all the threads to finish.
$_->join() for @threads;
print("Done\n");
return 0;
}
sub worker {
my $tid = threads->tid();
while (!$TERM && defined(my $job = $request_q->dequeue())) {
printf(" %2d <- Working\n", $tid);
# Do something with $job.
sleep(1+rand(3));
}
printf("Finished -> %2d\n", $tid);
}
这篇关于Perl与线程共享文件句柄的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!