ext/Thread/lock.tx Test lock primitive
ext/Thread/Makefile.PL Thread extension makefile writer
ext/Thread/Notes Thread notes
+ext/Thread/Queue.pmx Threadsafe queue
ext/Thread/queue.tx Test Thread::Queue module
ext/Thread/README Thread README
ext/Thread/README.threads Notes about multithreading
+ext/Thread/Semaphore.pmx Threadsafe semaphore
ext/Thread/specific.tx Test thread-specific user data
ext/Thread/sync.tx Test thread synchronisation
ext/Thread/sync2.tx Test thread synchronisation
ext/threads/Makefile.PL ithreads
ext/threads/README ithreads
ext/threads/shared/Makefile.PL thread shared variables
-ext/threads/shared/queue.pm Threadsafe queue.
ext/threads/shared/README thread shared variables
-ext/threads/shared/semaphore.pm Threadsafe semaphore
ext/threads/shared/shared.pm thread shared variables
ext/threads/shared/shared.xs thread shared variables
ext/threads/shared/t/0nothread.t Tests for basic shared array functionality.
ext/threads/shared/t/hv_refs.t Test shared hashes containing references
ext/threads/shared/t/hv_simple.t Tests for basic shared hash functionality.
ext/threads/shared/t/no_share.t Tests for disabled share on variables.
-ext/threads/shared/t/queue.t thread shared variables
-ext/threads/shared/t/semaphore.t test semaphore
ext/threads/shared/t/shared_attr.t Test :shared attribute
ext/threads/shared/t/sv_refs.t thread shared variables
ext/threads/shared/t/sv_simple.t thread shared variables
lib/Text/TabsWrap/t/wrap.t See if Text::Wrap::wrap works
lib/Text/Wrap.pm Paragraph formatter
lib/Thread.pm Thread extensions frontend
-lib/Thread/Queue.pm Thread synchronised queue objects
-lib/Thread/Semaphore.pm Thread semaphore objects
+lib/Thread/Queue.pm Threadsafe queue
+lib/Thread/Queue.t See if threadsafe queue works
+lib/Thread/Semaphore.pm Threadsafe semaphore
+lib/Thread/Semaphore.t See if threadsafe semaphore works
lib/Tie/Array.pm Base class for tied arrays
lib/Tie/Array/push.t Test for Tie::Array
lib/Tie/Array/splice.t Test for Tie::Array::SPLICE
--- /dev/null
+package Thread::Queue;
+use Thread qw(cond_wait cond_broadcast);
+
+=head1 NAME
+
+Thread::Queue - thread-safe queues (5.005-threads)
+
+=head1 CAVEAT
+
+This Perl installation is using the old unsupported "5.005 threads".
+Use of the old threads model is discouraged.
+
+For the whole story about the development of threads in Perl, and why
+you should B<not> be using "old threads" unless you know what you're
+doing, see the CAVEAT of the C<Thread> module.
+
+=head1 SYNOPSIS
+
+ use Thread::Queue;
+ my $q = new Thread::Queue;
+ $q->enqueue("foo", "bar");
+ my $foo = $q->dequeue; # The "bar" is still in the queue.
+ my $foo = $q->dequeue_nb; # returns "bar", or undef if the queue was
+ # empty
+ my $left = $q->pending; # returns the number of items still in the queue
+
+=head1 DESCRIPTION
+
+A queue, as implemented by C<Thread::Queue> is a thread-safe data structure
+much like a list. Any number of threads can safely add elements to the end
+of the list, or remove elements from the head of the list. (Queues don't
+permit adding or removing elements from the middle of the list)
+
+=head1 FUNCTIONS AND METHODS
+
+=over 8
+
+=item new
+
+The C<new> function creates a new empty queue.
+
+=item enqueue LIST
+
+The C<enqueue> method adds a list of scalars on to the end of the queue.
+The queue will grow as needed to accomodate the list.
+
+=item dequeue
+
+The C<dequeue> method removes a scalar from the head of the queue and
+returns it. If the queue is currently empty, C<dequeue> will block the
+thread until another thread C<enqueue>s a scalar.
+
+=item dequeue_nb
+
+The C<dequeue_nb> method, like the C<dequeue> method, removes a scalar from
+the head of the queue and returns it. Unlike C<dequeue>, though,
+C<dequeue_nb> won't block if the queue is empty, instead returning
+C<undef>.
+
+=item pending
+
+The C<pending> method returns the number of items still in the queue. (If
+there can be multiple readers on the queue it's best to lock the queue
+before checking to make sure that it stays in a consistent state)
+
+=back
+
+=head1 SEE ALSO
+
+L<Thread>
+
+=cut
+
+sub new {
+ my $class = shift;
+ return bless [@_], $class;
+}
+
+sub dequeue : locked : method {
+ my $q = shift;
+ cond_wait $q until @$q;
+ return shift @$q;
+}
+
+sub dequeue_nb : locked : method {
+ my $q = shift;
+ if (@$q) {
+ return shift @$q;
+ } else {
+ return undef;
+ }
+}
+
+sub enqueue : locked : method {
+ my $q = shift;
+ push(@$q, @_) and cond_broadcast $q;
+}
+
+sub pending : locked : method {
+ my $q = shift;
+ return scalar(@$q);
+}
+
+1;
-package threads::shared::semaphore;
+package Thread::Semaphore;
+use Thread qw(cond_wait cond_broadcast);
-use threads::shared;
+=head1 NAME
-our $VERSION = '1.00';
+Thread::Semaphore - thread-safe semaphores (5.005-threads)
-=head1 NAME
+=head1 CAVEAT
+
+This Perl installation is using the old unsupported "5.005 threads".
+Use of the old threads model is discouraged.
-threads::shared::semaphore - thread-safe semaphores
+For the whole story about the development of threads in Perl, and why
+you should B<not> be using "old threads" unless you know what you're
+doing, see the CAVEAT of the C<Thread> module.
=head1 SYNOPSIS
- use threads::shared::semaphore;
- my $s = new threads::shared::semaphore;
+ use Thread::Semaphore;
+ my $s = new Thread::Semaphore;
$s->up; # Also known as the semaphore V -operation.
# The guarded section is here
$s->down; # Also known as the semaphore P -operation.
# The default semaphore value is 1.
- my $s = new threads::shared::semaphore($initial_value);
+ my $s = new Thread::Semaphore($initial_value);
$s->up($up_value);
$s->down($up_value);
control access to anything you care to use them for.
Semaphores don't limit their values to zero or one, so they can be used to
-control access to some resource that there may be more than one of. (For
-example, filehandles). Increment and decrement amounts aren't fixed at one
+control access to some resource that may have more than one of. (For
+example, filehandles) Increment and decrement amounts aren't fixed at one
either, so threads can reserve or return multiple resources at once.
=head1 FUNCTIONS AND METHODS
=item down NUMBER
The C<down> method decreases the semaphore's count by the specified number,
-or by one if no number has been specified. If the semaphore's count would drop
+or one if no number has been specified. If the semaphore's count would drop
below zero, this method will block until such time that the semaphore's
count is equal to or larger than the amount you're C<down>ing the
semaphore's count by.
=item up NUMBER
The C<up> method increases the semaphore's count by the number specified,
-or by one if no number has been specified. This will unblock any thread blocked
+or one if no number's been specified. This will unblock any thread blocked
trying to C<down> the semaphore if the C<up> raises the semaphore count
-above the amount that the C<down>s are trying to decrement it by.
+above what the C<down>s are trying to decrement it by.
=back
sub new {
my $class = shift;
- my $val : shared = @_ ? shift : 1;
+ my $val = @_ ? shift : 1;
bless \$val, $class;
}
-sub down {
+sub down : locked : method {
my $s = shift;
- lock($$s);
my $inc = @_ ? shift : 1;
- cond_wait $$s until $$s >= $inc;
+ cond_wait $s until $$s >= $inc;
$$s -= $inc;
}
-sub up {
+sub up : locked : method {
my $s = shift;
- lock($$s);
my $inc = @_ ? shift : 1;
- ($$s += $inc) > 0 and cond_broadcast $$s;
+ ($$s += $inc) > 0 and cond_broadcast $s;
}
1;
'VERSION_FROM' => 'shared.pm', # finds $VERSION
'PM' => {
'shared.pm' => '$(INST_LIBDIR)/shared.pm',
- 'queue.pm' => '$(INST_LIBDIR)/shared/queue.pm',
- 'semaphore.pm' => '$(INST_LIBDIR)/shared/semaphore.pm',
},
'PREREQ_PM' => {}, # e.g., Module::Name => 1.1
($] >= 5.005 ? ## Add these new keywords supported since 5.005
+++ /dev/null
-package threads::shared::queue;
-
-use threads::shared;
-use strict;
-
-our $VERSION = '1.00';
-
-=head1 NAME
-
-threads::shared::queue - thread-safe queues
-
-=head1 SYNOPSIS
-
- use threads::shared::queue;
- my $q = new threads::shared::queue;
- $q->enqueue("foo", "bar");
- my $foo = $q->dequeue; # The "bar" is still in the queue.
- my $foo = $q->dequeue_nb; # returns "bar", or undef if the queue was
- # empty
- my $left = $q->pending; # returns the number of items still in the queue
-
-=head1 DESCRIPTION
-
-A queue, as implemented by C<threads::shared::queue> is a thread-safe
-data structure much like a list. Any number of threads can safely
-add elements to the end of the list, or remove elements from the head
-of the list. (Queues don't permit adding or removing elements from
-the middle of the list).
-
-=head1 FUNCTIONS AND METHODS
-
-=over 8
-
-=item new
-
-The C<new> function creates a new empty queue.
-
-=item enqueue LIST
-
-The C<enqueue> method adds a list of scalars on to the end of the queue.
-The queue will grow as needed to accommodate the list.
-
-=item dequeue
-
-The C<dequeue> method removes a scalar from the head of the queue and
-returns it. If the queue is currently empty, C<dequeue> will block the
-thread until another thread C<enqueue>s a scalar.
-
-=item dequeue_nb
-
-The C<dequeue_nb> method, like the C<dequeue> method, removes a scalar from
-the head of the queue and returns it. Unlike C<dequeue>, though,
-C<dequeue_nb> won't block if the queue is empty, instead returning
-C<undef>.
-
-=item pending
-
-The C<pending> method returns the number of items still in the queue.
-
-=back
-
-=head1 SEE ALSO
-
-L<threads>, L<threads::shared>
-
-=cut
-
-sub new {
- my $class = shift;
- my @q : shared = @_;
- return bless \@q, $class;
-}
-
-sub dequeue {
- my $q = shift;
- lock(@$q);
- cond_wait @$q until @$q;
- cond_signal @$q if @$q > 1;
- return shift @$q;
-}
-
-sub dequeue_nb {
- my $q = shift;
- lock(@$q);
- return shift @$q;
-}
-
-sub enqueue {
- my $q = shift;
- lock(@$q);
- push @$q, @_ and cond_signal @$q;
-}
-
-sub pending {
- my $q = shift;
- lock(@$q);
- return scalar(@$q);
-}
-
-1;
-
-
Note that you cannot explicitly unlock a variable; you can only wait
for the lock to go out of scope. If you need more fine-grained
-control, see L<threads::shared::semaphore>.
+control, see L<Thread::Semaphore>.
=item cond_wait VARIABLE
}
}
+# Switch in the 5.005-threads versions of he threadsafe queue and semaphore
+# modules if so needed.
+if ($Config{use5005threads}) {
+ for my $m (qw(Queue Semaphore)) {
+ copy("ext/Thread/$m.pmx", "$installprivlib/Thread/$m.pm")
+ }
+}
+
# Install main perl executables
# Make links to ordinary names if installbin directory isn't current directory.
package Thread::Queue;
+use threads::shared;
use strict;
-our $VERSION = '1.00';
-
-use Thread qw(cond_wait cond_broadcast);
-
-BEGIN {
- use Config;
- if ($Config{useithreads}) {
- require 'threads/shared/queue.pm';
- for my $meth (qw(new enqueue dequeue dequeue_nb pending)) {
- no strict 'refs';
- *{"Thread::Queue::$meth"} = \&{"threads::shared::queue::$meth"};
- }
- } elsif ($Config{use5005threads}) {
- for my $meth (qw(new enqueue dequeue dequeue_nb pending)) {
- no strict 'refs';
- *{"Thread::Queue::$meth"} = \&{"Thread::Queue::${meth}_othread"};
- }
- } else {
- require Carp;
- Carp::croak("This Perl has neither ithreads nor 5005threads");
- }
-}
-
+our $VERSION = '2.00';
=head1 NAME
-Thread::Queue - thread-safe queues (for old code only)
-
-=head1 CAVEAT
-
-For new code the use of the C<Thread::Queue> module is discouraged and
-the direct use of the C<threads>, C<threads::shared> and
-C<threads::shared::queue> modules is encouraged instead.
-
-For the whole story about the development of threads in Perl, and why you
-should B<not> be using this module unless you know what you're doing, see the
-CAVEAT of the C<Thread> module.
+Thread::Queue - thread-safe queues
=head1 SYNOPSIS
my $q = new Thread::Queue;
$q->enqueue("foo", "bar");
my $foo = $q->dequeue; # The "bar" is still in the queue.
- my $foo = $q->dequeue_nb; # returns "bar", or undef if the queue was
- # empty
+ my $foo = $q->dequeue_nb; # returns "bar", or undef if the queue was empty
my $left = $q->pending; # returns the number of items still in the queue
=head1 DESCRIPTION
-A queue, as implemented by C<Thread::Queue> is a thread-safe data structure
-much like a list. Any number of threads can safely add elements to the end
-of the list, or remove elements from the head of the list. (Queues don't
-permit adding or removing elements from the middle of the list)
+A queue, as implemented by C<Thread::Queue> is a thread-safe
+data structure much like a list. Any number of threads can safely
+add elements to the end of the list, or remove elements from the head
+of the list. (Queues don't permit adding or removing elements from
+the middle of the list).
=head1 FUNCTIONS AND METHODS
=item enqueue LIST
The C<enqueue> method adds a list of scalars on to the end of the queue.
-The queue will grow as needed to accomodate the list.
+The queue will grow as needed to accommodate the list.
=item dequeue
=item pending
-The C<pending> method returns the number of items still in the queue. (If
-there can be multiple readers on the queue it's best to lock the queue
-before checking to make sure that it stays in a consistent state)
+The C<pending> method returns the number of items still in the queue.
=back
=head1 SEE ALSO
-L<Thread>
+L<threads>, L<threads::shared>
=cut
-sub new_othread {
+sub new {
my $class = shift;
- return bless [@_], $class;
+ my @q : shared = @_;
+ return bless \@q, $class;
}
-sub dequeue_othread : locked : method {
+sub dequeue {
my $q = shift;
- cond_wait $q until @$q;
+ lock(@$q);
+ cond_wait @$q until @$q;
+ cond_signal @$q if @$q > 1;
return shift @$q;
}
-sub dequeue_nb_othread : locked : method {
- my $q = shift;
- if (@$q) {
+sub dequeue_nb {
+ my $q = shift;
+ lock(@$q);
return shift @$q;
- } else {
- return undef;
- }
}
-sub enqueue_othread : locked : method {
+sub enqueue {
my $q = shift;
- push(@$q, @_) and cond_broadcast $q;
+ lock(@$q);
+ push @$q, @_ and cond_signal @$q;
}
-sub pending_othread : locked : method {
- return scalar(@{(shift)});
+sub pending {
+ my $q = shift;
+ lock(@$q);
+ return scalar(@$q);
}
1;
+
+
push @INC ,'../lib';
require Config; import Config;
unless ($Config{'useithreads'}) {
- print "1..0 # Skip: might still hang\n";
+ print "1..0 # Skip: no ithreads\n";
exit 0;
}
}
use strict;
use threads;
-use threads::shared::queue;
+use Thread::Queue;
-my $q = new threads::shared::queue;
+my $q = new Thread::Queue;
$|++;
print "1..26\n";
package Thread::Semaphore;
-use strict;
-
-our $VERSION = '1.00';
-
-use Thread qw(cond_wait cond_broadcast);
-
-BEGIN {
- use Config;
- if ($Config{useithreads}) {
- require 'threads/shared/semaphore.pm';
- for my $meth (qw(new up down)) {
- no strict 'refs';
- *{"Thread::Semaphore::$meth"} = \&{"threads::shared::semaphore::$meth"};
- }
- } elsif ($Config{use5005threads}) {
- for my $meth (qw(new up down)) {
- no strict 'refs';
- *{"Thread::Semaphore::$meth"} = \&{"Thread::Semaphore::${meth}_othread"};
- }
- } else {
- require Carp;
- Carp::croak("This Perl has neither ithreads nor 5005threads");
- }
-}
+use threads::shared;
+our $VERSION = '2.00';
=head1 NAME
-Thread::Semaphore - thread-safe semaphores (for old code only)
-
-=head1 CAVEAT
-
-For new code the use of the C<Thread::Semaphore> module is discouraged and
-the direct use of the C<threads>, C<threads::shared> and
-C<threads::shared::semaphore> modules is encouraged instead.
-
-For the whole story about the development of threads in Perl, and why you
-should B<not> be using this module unless you know what you're doing, see the
-CAVEAT of the C<Thread> module.
+Thread::Semaphore - thread-safe semaphores
=head1 SYNOPSIS
control access to anything you care to use them for.
Semaphores don't limit their values to zero or one, so they can be used to
-control access to some resource that may have more than one of. (For
-example, filehandles) Increment and decrement amounts aren't fixed at one
+control access to some resource that there may be more than one of. (For
+example, filehandles). Increment and decrement amounts aren't fixed at one
either, so threads can reserve or return multiple resources at once.
=head1 FUNCTIONS AND METHODS
=item down NUMBER
The C<down> method decreases the semaphore's count by the specified number,
-or one if no number has been specified. If the semaphore's count would drop
+or by one if no number has been specified. If the semaphore's count would drop
below zero, this method will block until such time that the semaphore's
count is equal to or larger than the amount you're C<down>ing the
semaphore's count by.
=item up NUMBER
The C<up> method increases the semaphore's count by the number specified,
-or one if no number's been specified. This will unblock any thread blocked
+or by one if no number has been specified. This will unblock any thread blocked
trying to C<down> the semaphore if the C<up> raises the semaphore count
-above what the C<down>s are trying to decrement it by.
+above the amount that the C<down>s are trying to decrement it by.
=back
=cut
-sub new_othread {
+sub new {
my $class = shift;
- my $val = @_ ? shift : 1;
+ my $val : shared = @_ ? shift : 1;
bless \$val, $class;
}
-sub down_othread : locked : method {
+sub down {
my $s = shift;
+ lock($$s);
my $inc = @_ ? shift : 1;
- cond_wait $s until $$s >= $inc;
+ cond_wait $$s until $$s >= $inc;
$$s -= $inc;
}
-sub up_othread : locked : method {
+sub up {
my $s = shift;
+ lock($$s);
my $inc = @_ ? shift : 1;
- ($$s += $inc) > 0 and cond_broadcast $s;
+ ($$s += $inc) > 0 and cond_broadcast $$s;
}
1;
push @INC ,'../lib';
require Config; import Config;
unless ($Config{'useithreads'}) {
- print "1..0 # Skip: no threads\n";
+ print "1..0 # Skip: no ithreads\n";
exit 0;
}
}
print "1..1\n";
use threads;
-use threads::shared::semaphore;
+use Thread::Semaphore;
print "ok 1\n";
=item Thread::Queue
-Thread-safe queues (for old code only)
+Thread-safe queues
=item Thread::Semaphore
-Thread-safe semaphores (for old code only)
+Thread-safe semaphores
=item Tie::Array
this:
use threads;
- use threads::shared::queue;
+ use Thread::Queue;
- my $DataQueue = threads::shared::queue->new;
+ my $DataQueue = Thread::Queue->new;
$thr = threads->new(sub {
while ($DataElement = $DataQueue->dequeue) {
print "Popped $DataElement off the queue\n";
$DataQueue->enqueue(undef);
$thr->join;
-You create the queue with C<new threads::shared::queue>. Then you can
+You create the queue with C<new Thread::Queue>. Then you can
add lists of scalars onto the end with enqueue(), and pop scalars off
the front of it with dequeue(). A queue has no fixed size, and can grow
as needed to hold everything pushed on to it.
gives a quick demonstration:
use threads qw(yield);
- use threads::shared::semaphore;
+ use Thread::Semaphore;
- my $semaphore = new threads::shared::semaphore;
+ my $semaphore = new Thread::Semaphore;
my $GlobalVariable : shared = 0;
$thr1 = new threads \&sample_sub, 1;
of these defaults simply by passing in different values:
use threads;
- use threads::shared::semaphore;
- my $semaphore = threads::shared::semaphore->new(5);
+ use Thread::Semaphore;
+ my $semaphore = Thread::Semaphore->new(5);
# Creates a semaphore with the counter set to five
$thr1 = threads->new(\&sub1);
4 use strict;
5
6 use threads;
- 7 use threads::shared::queue;
+ 7 use Thread::Queue;
8
- 9 my $stream = new threads::shared::queue;
+ 9 my $stream = new Thread::Queue;
10 my $kid = new threads(\&check_num, $stream, 2);
11
12 for my $i ( 3 .. 1000 ) {
19 sub check_num {
20 my ($upstream, $cur_prime) = @_;
21 my $kid;
- 22 my $downstream = new threads::shared::queue;
+ 22 my $downstream = new Thread::Queue;
23 while (my $num = $upstream->dequeue) {
24 next unless $num % $cur_prime;
25 if ($kid) {
Net::Cmd, Net::Config, Net::Domain, Net::FTP, Net::NNTP, Net::Netrc,
Net::POP3, Net::Ping, Net::SMTP, Net::Time, Net::hostent, Net::libnetFAQ,
Net::netent, Net::protoent, Net::servent, O, ODBM_File, Opcode, POSIX,
-PerlIO, Pod::Checker, Pod::Find, Pod::Functions, Pod::Html,
-Pod::InputObjects, Pod::LaTeX, Pod::Man, Pod::ParseLink, Pod::ParseUtils,
-Pod::Parser, Pod::Plainer, Pod::Select, Pod::Text, Pod::Text::Color,
-Pod::Text::Overstrike, Pod::Text::Termcap, Pod::Usage, SDBM_File, Safe,
-Search::Dict, SelectSaver, SelfLoader, Shell, Socket, Storable, Switch,
-Symbol, Term::ANSIColor, Term::Cap, Term::Complete, Term::ReadLine, Test,
-Test::Builder, Test::Harness, Test::Harness::Assert,
+PerlIO, PerlIO::via::QuotedPrint, Pod::Checker, Pod::Find, Pod::Functions,
+Pod::Html, Pod::InputObjects, Pod::LaTeX, Pod::Man, Pod::ParseLink,
+Pod::ParseUtils, Pod::Parser, Pod::Plainer, Pod::Select, Pod::Text,
+Pod::Text::Color, Pod::Text::Overstrike, Pod::Text::Termcap, Pod::Usage,
+SDBM_File, Safe, Search::Dict, SelectSaver, SelfLoader, Shell, Socket,
+Storable, Switch, Symbol, Term::ANSIColor, Term::Cap, Term::Complete,
+Term::ReadLine, Test, Test::Builder, Test::Harness, Test::Harness::Assert,
Test::Harness::Iterator, Test::Harness::Straps, Test::More, Test::Simple,
Test::Tutorial, Text::Abbrev, Text::Balanced, Text::ParseWords,
Text::Soundex, Text::Tabs, Text::Wrap, Thread, Thread::Queue,
=back
-=head2 threadshared::queue, threads::shared::queue - thread-safe queues
-
-=over 4
-
-=item SYNOPSIS
-
-=item DESCRIPTION
-
-=item FUNCTIONS AND METHODS
-
-new, enqueue LIST, dequeue, dequeue_nb, pending
-
-=item SEE ALSO
-
-=back
-
-=head2 threadshared::semaphore, threads::shared::semaphore - thread-safe
-semaphores
-
-=over 4
-
-=item SYNOPSIS
-
-=item DESCRIPTION
-
-=item FUNCTIONS AND METHODS
-
-new, new NUMBER, down, down NUMBER, up, up NUMBER
-
-=back
-
=head2 threadshared::shared, threads::shared - Perl extension for sharing
data structures between threads
=item DESCRIPTION
$thread = threads->create(function, LIST), $thread->join, $thread->detach,
-threads->self, $thread->tid, threads->yield();, threads->list();, async
-BLOCK;
+threads->self, $thread->tid, threads->object( tid ), threads->yield();,
+threads->list();, async BLOCK;
=item WARNINGS
=back
-=head2 threadshared::queue, threads::shared::queue - thread-safe queues
-
-=over 4
-
-=item SYNOPSIS
-
-=item DESCRIPTION
-
-=item FUNCTIONS AND METHODS
-
-new, enqueue LIST, dequeue, dequeue_nb, pending
-
-=item SEE ALSO
-
-=back
-
-=head2 threadshared::semaphore, threads::shared::semaphore - thread-safe
-semaphores
-
-=over 4
-
-=item SYNOPSIS
-
-=item DESCRIPTION
-
-=item FUNCTIONS AND METHODS
-
-new, new NUMBER, down, down NUMBER, up, up NUMBER
-
-=back
-
=head2 utf8 - Perl pragma to enable/disable UTF-8 (or UTF-EBCDIC) in source
code
=back
-=head2 Thread::Queue - thread-safe queues (for old code only)
+=head2 Thread::Queue - thread-safe queues
=over 4
-=item CAVEAT
-
=item SYNOPSIS
=item DESCRIPTION
=back
-=head2 Thread::Semaphore - thread-safe semaphores (for old code only)
+=head2 Thread::Semaphore - thread-safe semaphores
=over 4
-=item CAVEAT
-
=item SYNOPSIS
=item DESCRIPTION