Coro

 view release on metacpan or  search on metacpan

Coro.pm  view on Meta::CPAN

general) run in parallel at the same time even on SMP machines. The
specific flavor of thread offered by this module also guarantees you that
it will not switch between threads unless necessary, at easily-identified
points in your program, so locking and parallel access are rarely an
issue, making thread programming much safer and easier than using other
thread models.

Unlike the so-called "Perl threads" (which are not actually real threads
but only the windows process emulation (see section of same name for
more details) ported to UNIX, and as such act as processes), Coro
provides a full shared address space, which makes communication between
threads very easy. And coro threads are fast, too: disabling the Windows
process emulation code in your perl and using Coro can easily result in
a two to four times speed increase for your programs. A parallel matrix
multiplication benchmark (very communication-intensive) runs over 300
times faster on a single core than perls pseudo-threads on a quad core
using all four cores.

Coro achieves that by supporting multiple running interpreters that share
data, which is especially useful to code pseudo-parallel processes and
for event-based programming, such as multiple HTTP-GET requests running
concurrently. See L<Coro::AnyEvent> to learn more on how to integrate Coro
into an event-based environment.

In this module, a thread is defined as "callchain + lexical variables +
some package variables + C stack), that is, a thread has its own callchain,
its own set of lexicals and its own set of perls most important global
variables (see L<Coro::State> for more configuration and background info).

See also the C<SEE ALSO> section at the end of this document - the Coro
module family is quite large.

=head1 CORO THREAD LIFE CYCLE

During the long and exciting (or not) life of a coro thread, it goes
through a number of states:

=over 4

=item 1. Creation

The first thing in the life of a coro thread is it's creation -
obviously. The typical way to create a thread is to call the C<async
BLOCK> function:

   async {
      # thread code goes here
   };

You can also pass arguments, which are put in C<@_>:

   async {
      print $_[1]; # prints 2
   } 1, 2, 3;

This creates a new coro thread and puts it into the ready queue, meaning
it will run as soon as the CPU is free for it.

C<async> will return a Coro object - you can store this for future
reference or ignore it - a thread that is running, ready to run or waiting
for some event is alive on it's own.

Another way to create a thread is to call the C<new> constructor with a
code-reference:

   new Coro sub {
      # thread code goes here
   }, @optional_arguments;

This is quite similar to calling C<async>, but the important difference is
that the new thread is not put into the ready queue, so the thread will
not run until somebody puts it there. C<async> is, therefore, identical to
this sequence:

   my $coro = new Coro sub {
      # thread code goes here
   };
   $coro->ready;
   return $coro;

=item 2. Startup

When a new coro thread is created, only a copy of the code reference
and the arguments are stored, no extra memory for stacks and so on is
allocated, keeping the coro thread in a low-memory state.

Only when it actually starts executing will all the resources be finally
allocated.

The optional arguments specified at coro creation are available in C<@_>,
similar to function calls.

=item 3. Running / Blocking

A lot can happen after the coro thread has started running. Quite usually,
it will not run to the end in one go (because you could use a function
instead), but it will give up the CPU regularly because it waits for
external events.

As long as a coro thread runs, its Coro object is available in the global
variable C<$Coro::current>.

The low-level way to give up the CPU is to call the scheduler, which
selects a new coro thread to run:

   Coro::schedule;

Since running threads are not in the ready queue, calling the scheduler
without doing anything else will block the coro thread forever - you need
to arrange either for the coro to put woken up (readied) by some other
event or some other thread, or you can put it into the ready queue before
scheduling:

   # this is exactly what Coro::cede does
   $Coro::current->ready;
   Coro::schedule;

All the higher-level synchronisation methods (Coro::Semaphore,
Coro::rouse_*...) are actually implemented via C<< ->ready >> and C<<
Coro::schedule >>.

Coro.pm  view on Meta::CPAN

Note that while this will try to free some of the main interpreter
resources if the calling coro isn't the main coro, but one
cannot free all of them, so if a coro that is not the main coro
calls this function, there will be some one-time resource leak.

=cut

sub killall {
   for (Coro::State::list) {
      $_->cancel
         if $_ != $current && UNIVERSAL::isa $_, "Coro";
   }
}

=back

=head1 CORO OBJECT METHODS

These are the methods you can call on coro objects (or to create
them).

=over 4

=item new Coro \&sub [, @args...]

Create a new coro and return it. When the sub returns, the coro
automatically terminates as if C<terminate> with the returned values were
called. To make the coro run you must first put it into the ready
queue by calling the ready method.

See C<async> and C<Coro::State::new> for additional info about the
coro environment.

=cut

sub _coro_run {
   terminate &{+shift};
}

=item $success = $coro->ready

Put the given coro into the end of its ready queue (there is one
queue for each priority) and return true. If the coro is already in
the ready queue, do nothing and return false.

This ensures that the scheduler will resume this coro automatically
once all the coro of higher priority and all coro of the same
priority that were put into the ready queue earlier have been resumed.

=item $coro->suspend

Suspends the specified coro. A suspended coro works just like any other
coro, except that the scheduler will not select a suspended coro for
execution.

Suspending a coro can be useful when you want to keep the coro from
running, but you don't want to destroy it, or when you want to temporarily
freeze a coro (e.g. for debugging) to resume it later.

A scenario for the former would be to suspend all (other) coros after a
fork and keep them alive, so their destructors aren't called, but new
coros can be created.

=item $coro->resume

If the specified coro was suspended, it will be resumed. Note that when
the coro was in the ready queue when it was suspended, it might have been
unreadied by the scheduler, so an activation might have been lost.

To avoid this, it is best to put a suspended coro into the ready queue
unconditionally, as every synchronisation mechanism must protect itself
against spurious wakeups, and the one in the Coro family certainly do
that.

=item $state->is_new

Returns true iff this Coro object is "new", i.e. has never been run
yet. Those states basically consist of only the code reference to call and
the arguments, but consumes very little other resources. New states will
automatically get assigned a perl interpreter when they are transferred to.

=item $state->is_zombie

Returns true iff the Coro object has been cancelled, i.e.
it's resources freed because they were C<cancel>'ed, C<terminate>'d,
C<safe_cancel>'ed or simply went out of scope.

The name "zombie" stems from UNIX culture, where a process that has
exited and only stores and exit status and no other resources is called a
"zombie".

=item $is_ready = $coro->is_ready

Returns true iff the Coro object is in the ready queue. Unless the Coro
object gets destroyed, it will eventually be scheduled by the scheduler.

=item $is_running = $coro->is_running

Returns true iff the Coro object is currently running. Only one Coro object
can ever be in the running state (but it currently is possible to have
multiple running Coro::States).

=item $is_suspended = $coro->is_suspended

Returns true iff this Coro object has been suspended. Suspended Coros will
not ever be scheduled.

=item $coro->cancel ($arg...)

Terminate the given Coro thread and make it return the given arguments as
status (default: an empty list). Never returns if the Coro is the
current Coro.

This is a rather brutal way to free a coro, with some limitations - if
the thread is inside a C callback that doesn't expect to be canceled,
bad things can happen, or if the cancelled thread insists on running
complicated cleanup handlers that rely on its thread context, things will
not work.

Any cleanup code being run (e.g. from C<guard> blocks, destructors and so
on) will be run without a thread context, and is not allowed to switch



( run in 1.337 second using v1.01-cache-2.11-cpan-99c4e6809bf )