parallel

目录

Runtime Objects

Each runtime represents a single PHP thread, the thread is created (and bootstrapped) upon construction. The thread then waits for tasks to be scheduled: Scheduled tasks will be executed FIFO and then the thread will resume waiting until more tasks are scheduled, or it's closed, killed, or destroyed by the normal scoping rules of PHP objects.

Warning

When a runtime is destroyed by the normal scoping rules of PHP objects, it will first execute all of the tasks that were scheduled, and block while doing so.

Runtime Bootstrapping

When a new runtime is created, it does not share code with the thread (or process) that created it. This means it doesn't have the same classes and functions loaded, nor the same autoloader set. In some cases, a very lightweight runtime is desirable because the tasks that will be scheduled do not need access to the code in the parent thread. In those cases where the tasks do need to access the same code, it is enough to set an autoloader as the bootstrap.

Note:

preloading may be used in conjunction with parallel, in this case preloaded code is available without bootstrapping

类摘要

parallel\Runtime

final class parallel\Runtime {

/* Create */

public __construct ( void )

public __construct ( string $bootstrap )

/* Execute */

public ?Future run ( Closure $task )

public ?Future run ( Closure $task , array $argv )

/* Join */

public void close ( void )

public void kill ( void )

}

parallel\Runtime::__construct

Runtime Construction

说明

public parallel\Runtime::__construct ( void )

Shall construct a new runtime without bootstrapping.

public parallel\Runtime::__construct ( string $bootstrap )

Shall construct a bootstrapped runtime.

参数

bootstrap
The location of a bootstrap file, generally an autoloader.

Exceptions

Warning

Shall throw \parallel\Runtime\Error if thread could not be created

Warning

Shall throw \parallel\Runtime\Bootstrap if bootstrapping failed

parallel\Runtime::run

Execution

说明

public ?Future parallel\Runtime::run ( Closure $task )

Shall schedule task for execution in parallel.

public ?Future parallel\Runtime::run ( Closure $task , array $argv )

Shall schedule task for execution in parallel, passing argv at execution time.

参数

task
A Closure with specific characteristics.

argv
An array of arguments with specific characteristics to be passed to task at execution time.

Task Characteristics

Closures scheduled for parallel execution must not:

  • accept or return by reference
  • accept or return internal objects (see notes)
  • execute a limited set of instructions

Instructions prohibited in Closures intended for parallel execution are:

  • yield
  • use by-reference
  • declare class
  • declare named function

Note:

Nested closures may yield or use by-reference, but must not contain class or named function declarations.

Note:

No instructions are prohibited in the files which the task may include.

Arguments Characteristics

Arguments must not:

  • contain references
  • contain resources
  • contain internal objects (see notes)

Note:

In the case of file stream resources, the resource will be cast to the file descriptor and passed as int where possible, this is unsupported on Windows.

Internal Objects Notes

Internal objects generally use a custom structure which cannot be copied by value safely, PHP currently lacks the mechanics to do this (without serialization) and so only objects that do not use a custom structure may be shared.

Some internal objects do not use a custom structure, for example parallel\Events\Event and so may be shared.

Closures are a special kind of internal object and support being copied by value, and so may be shared.

Channels are central to writing parallel code and support concurrent access and execution by necessity, and so may be shared.

Warning

A user class that extends an internal class may use a custom structure as defined by the internal class, in which case they cannot be copied by value safely, and so may not be shared.

返回值

Warning

The return \parallel\Future must not be ignored when the task contains a return or throw statement.

Exceptions

Warning

Shall throw \parallel\Runtime\Error\Closed if \parallel\Runtime was closed.

Warning

Shall throw \parallel\Runtime\Error\IllegalFunction if task is a closure created from an internal function.

Warning

Shall throw \parallel\Runtime\Error\IllegalInstruction if task contains illegal instructions.

Warning

Shall throw \parallel\Runtime\Error\IllegalParameter if task accepts or argv contains illegal variables.

Warning

Shall throw \parallel\Runtime\Error\IllegalReturn if task returns illegally.

parallel\Runtime::close

Runtime Graceful Join

说明

public void parallel\Runtime::close ( void )

Shall request that the runtime shutsdown.

Note:

Tasks scheduled for execution will be executed before the shutdown occurs.

Exceptions

Warning

Shall throw \parallel\Runtime\Error\Closed if Runtime was already closed.

parallel\Runtime::kill

Runtime Join

说明

public void parallel\Runtime::kill ( void )

Shall attempt to force the runtime to shutdown.

Note:

Tasks scheduled for execution will not be executed, the currently running task shall be interrupted.

Warning

Internal function calls in progress cannot be interrupted.

Exceptions

Warning

Shall throw \parallel\Runtime\Error\Closed if Runtime was closed.

Futures

A Future represents the return value or uncaught exception from a task, and exposes an API for cancellation.

示例 #1 Example showing Future as return value

<?php
$runtime = new \parallel\Runtime;
$future  = $runtime->run(function(){
    return "World";
});
printf("Hello %s\n", $future->value());
?>

以上例程的输出类似于:

Hello World

The behaviour of a future also allows it to be used as a simple synchronization point even where the task does not return a value explicitly.

示例 #2 Example showing Future as synchronization point

<?php
$runtime = new \parallel\Runtime;
$future  = $runtime->run(function(){
    echo "in child ";
    for ($i = 0; $i < 500; $i++) {
        if ($i % 10 == 0) {
            echo ".";
        }
    }
    echo " leaving child";
});

$future->value();
echo "\nparent continues\n";
?>

以上例程的输出类似于:

in child .................................................. leaving child
parent continues

类摘要

parallel\Future

final class parallel\Future {

/* Resolution */

public mixed value ( void )

/* State */

public bool cancelled ( void )

public bool done ( void )

/* Cancellation */

public bool cancel ( void )

}

parallel\Future::cancel

Cancellation

说明

public bool parallel\Future::cancel ( void )

Shall try to cancel the task

Note:

If task is running, it will be interrupted.

Warning

Internal function calls in progress cannot be interrupted.

Exceptions

Warning

Shall throw \parallel\Future\Error\Killed if \parallel\Runtime executing task was killed.

Warning

Shall throw \parallel\Future\Error\Cancelled if task was already cancelled.

parallel\Future::cancelled

State Detection

说明

public bool parallel\Future::cancelled ( void )

Shall indicate if the task was cancelled

parallel\Future::done

State Detection

说明

public bool parallel\Future::done ( void )

Shall indicate if the task is completed

parallel\Future::value

Resolution

说明

public mixed parallel\Future::value ( void )

Shall return (and if necessary wait for) return from task

Exceptions

Warning

Shall throw \parallel\Future\Error if waiting failed (internal error).

Warning

Shall throw \parallel\Future\Error\Killed if \parallel\Runtime executing task was killed.

Warning

Shall throw \parallel\Future\Error\Cancelled if task was cancelled.

Warning

Shall throw \parallel\Future\Error\Foreign if task raised an unrecognized uncaught exception.

Warning

Shall rethrow \Throwable uncaught in task

Unbuffered Channels

An unbuffered channel will block on calls to parallel\Channel::send until there is a receiver, and block on calls to parallel\Channel::recv until there is a sender. This means an unbuffered channel is not only a way to share data among tasks but also a simple method of synchronization.

An unbuffered channel is the fastest way to share data among tasks, requiring the least copying.

Buffered Channels

A buffered channel will not block on calls to parallel\Channel::send until capacity is reached, calls to parallel\Channel::recv will block until there is data in the buffer.

Closures over Channels

A powerful feature of parallel channels is that they allow the exchange of closures between tasks (and runtimes).

When a closure is sent over a channel the closure is buffered, it doesn't change the buffering of the channel transmitting the closure, but it does effect the static scope inside the closure: The same closure sent to different runtimes, or the same runtime, will not share their static scope.

This means that whenever a closure is executed that was transmitted by a channel, static state will be as it was when the closure was buffered.

Anonymous Channels

The anonymous channel constructor allows the programmer to avoid assigning names to every channel: parallel will generate a unique name for anonymous channels.

类摘要

parallel\Channel

final class parallel\Channel {

/* Anonymous Constructor */

public __construct ( void )

public __construct ( int $capacity )

/* Access */

public Channel make ( string $name )

public Channel make ( string $name , int $capacity )

public Channel open ( string $name )

/* Sharing */

public mixed recv ( void )

public void send ( mixed $value )

/* Closing */

public void close ( void )

/* Constant for Infinitely Buffered */

const Infinite ;

}

parallel\Channel::__construct

Channel Construction

说明

public parallel\Channel::__construct ( void )

Shall make an anonymous unbuffered channel

public parallel\Channel::__construct ( int $capacity )

Shall make an anonymous buffered channel with the given capacity

参数

capacity
May be Channel::Infinite or a positive integer

parallel\Channel::make

Access

说明

public Channel parallel\Channel::make ( string $name )

Shall make an unbuffered channel with the given name

public Channel parallel\Channel::make ( string $name , int $capacity )

Shall make a buffered channel with the given name and capacity

参数

name
The name of the channel.

capacity
May be Channel::Infinite or a positive integer

Exceptions

Warning

Shall throw \parallel\Channel\Error\Existence if channel already exists.

parallel\Channel::open

Access

说明

public Channel parallel\Channel::open ( string $name )

Shall open the channel with the given name

Exceptions

Warning

Shall throw \parallel\Channel\Error\Existence if channel does not exist.

parallel\Channel::recv

Sharing

说明

public mixed parallel\Channel::recv ( void )

Shall recv a value from this channel

Exceptions

Warning

Shall throw \parallel\Channel\Error\Closed if channel is closed.

parallel\Channel::send

Sharing

说明

public void parallel\Channel::send ( mixed $value )

Shall send the given value on this channel

Exceptions

Warning

Shall throw \parallel\Channel\Error\Closed if channel is closed.

Warning

Shall throw \parallel\Channel\Error\IllegalValue if value is illegal.

parallel\Channel::close

Closing

说明

public void parallel\Channel::close ( void )

Shall close this channel

Exceptions

Warning

Shall throw \parallel\Channel\Error\Closed if channel is closed.

The Event Loop

The Event loop monitors the state of sets of futures and or channels (targets) in order to perform read ( parallel\Future::value, parallel\Channel::recv) and write ( parallel\Channel::send) operations as the targets become available and the operations may be performed without blocking the event loop.

类摘要

parallel\Events

final class parallel\Events implements Countable , Traversable {

/* Input */

public void setInput ( Input $input )

/* Targets */

public void addChannel ( parallel\Channel $channel )

public void addFuture ( string $name , parallel\Future $future )

public void remove ( string $target )

/* Behaviour */

public void setBlocking ( bool $blocking )

public void setTimeout ( int $timeout )

/* Polling */

public ?Event poll ( void )

}

parallel\Events::setBlocking

Behaviour

说明

By default when events are polled for, blocking will occur (at the PHP level) until the first event can be returned: Setting blocking mode to false will cause poll to return control if the first target polled is not ready.

This differs from setting a timeout of 0 with parallel\Events::setTimeout, since a timeout of 0, while allowed, will cause an exception to be raised, which may be extremely slow or wasteful if what is really desired is non-blocking behaviour.

A non-blocking loop effects the return value of parallel\Events::poll, such that it may be null before all events have been processed.

public void parallel\Events::setBlocking ( bool $blocking )

Shall set blocking mode

Exceptions

Warning

Shall throw \parallel\Events\Error if loop has timeout set.

parallel\Events::setTimeout

Behaviour

说明

By default when events are polled for, blocking will occur (at the PHP level) until the first event can be returned: Setting the timeout causes an exception to be thrown when the timeout is reached.

This differs from setting blocking mode to false with parallel\Events::setBlocking, which will not cause an exception to be thrown.

public void parallel\Events::setTimeout ( int $timeout )

Shall set the timeout in microseconds

Exceptions

Warning

Shall throw \parallel\Events\Error if loop is non-blocking.

parallel\Events::setInput

Input

说明

public void parallel\Events::setInput ( Input $input )

Shall set input for this event loop

parallel\Events::addChannel

Targets

说明

public void parallel\Events::addChannel ( parallel\Channel $channel )

Shall watch for events on the given channel

Exceptions

Warning

Shall throw \parallel\Events\Error\Existence if channel was already added.

parallel\Events::addFuture

Targets

说明

public void parallel\Events::addFuture ( string $name , parallel\Future $future )

Shall watch for events on the given future

Exceptions

Warning

Shall throw \parallel\Events\Error\Existence if target with the given name was already added.

parallel\Events::remove

Targets

说明

public void parallel\Events::remove ( string $target )

Shall remove the given target

Exceptions

Warning

Shall throw \parallel\Events\Error\Existence if target with the given name was not found.

parallel\Events::poll

Polling

说明

public ?Event parallel\Events::poll ( void )

Shall poll for the next event

返回值

Should there be no targets remaining, null shall be returned

Should this be a non-blocking loop, and blocking would occur, null shall be returned

Otherwise, the parallel\Events\Event returned describes the event.

Exceptions

Warning

Shall throw \parallel\Events\Error\Timeout if timeout is used and reached.

Events Input

An Input object is a container for data that the parallel\Events object will write to parallel\Channel objects as they become available. Multiple event loops may share an Input container - parallel does not verify the contents of the container when it is set as the input for a parallel\Events object.

Note:

When a parallel\Events object performs a write, the target is removed from the input object as if class="methodname">parallel\Events\Input::remove were called.

类摘要

parallel\Events\Input

final class parallel\Events\Input {

public void add ( string $target , mixed $value )

public void remove ( string $target )

public void clear ( void )

}

parallel\Events\Input::add

Inputs

说明

public void parallel\Events\Input::add ( string $target , mixed $value )

Shall set input for the given target

Exceptions

Warning

Shall throw \parallel\Events\Input\Error\Existence if input for target already exists.

Warning

Shall throw \parallel\Events\Input\Error\IllegalValue if value is illegal (object, null).

parallel\Events\Input::clear

Inputs

说明

public void parallel\Events\Input::clear ( void )

Shall remove input for all targets

parallel\Events\Input::remove

Inputs

说明

public void parallel\Events\Input::remove ( string $target )

Shall remove input for the given target

Exceptions

Warning

Shall throw \parallel\Events\Input\Error\Existence if input for target does not exist.

Event Objects

When an Event is returned, Event::$object shall be removed from the loop that returned it, should the event be a write event the Input for Event::$source shall also be removed.

类摘要

parallel\Events\Event

final class parallel\Events\Event {

/* Shall be one of Event\Type constants */

public int $type ;

/* Shall be the source of the event (target name) */

public string $source ;

/* Shall be either Future or Channel */

public object $object ;

/* Shall be set for Read/Error events */

public $value ;

}

类摘要

parallel\Events\Event\Type

final class parallel\Events\Event\Type {

/* Event::$object was read into Event::$value */

const Read ;

/* Input for Event::$source written to Event::$object */

const Write ;

/* Event::$object (Channel) was closed */

const Close ;

/* Event::$object (Future) was cancelled */

const Cancel ;

/* Runtime executing Event::$object (Future) was killed */

const Kill ;

/* Event::$object (Future) raised error */

const Error ;

}

Low Level Synchronization

The parallel\Sync class provides access to low level synchronization primitives, mutex, condition variables, and allows the implementation of semaphores.

Synchronization for most applications is much better implemented using channels, however, in some cases authors of low level code may find it useful to be able to access these lower level mechanisms.

类摘要

parallel\Sync

final class parallel\Sync {

/* Constructor */

public __construct ( void )

public __construct ( scalar $value )

/* Access */

public scalar get ( void )

public set ( scalar $value )

/* Synchronization */

public wait ( void )

public notify ([ bool $all ] )

public __invoke ( callable $critical )

}

parallel\Sync::__construct

Construction

说明

public parallel\Sync::__construct ( void )

Shall construct a new synchronization object with no value

public parallel\Sync::__construct ( scalar $value )

Shall construct a new synchronization object containing the given scalar value

Exceptions

Warning

Shall throw \parallel\Sync\Error\IllegalValue if value is non-scalar.

parallel\Sync::get

Access

说明

public scalar parallel\Sync::get ( void )

Shall atomically return the syncrhonization objects value

parallel\Sync::set

Access

说明

public parallel\Sync::set ( scalar $value )

Shall atomically set the value of the synchronization object

Exceptions

Warning

Shall throw \parallel\Sync\Error\IllegalValue if value is non-scalar.

parallel\Sync::wait

Synchronization

说明

public parallel\Sync::wait ( void )

Shall wait for notification on this synchronization object

parallel\Sync::notify

Synchronization

说明

public parallel\Sync::notify ([ bool $all ] )

Shall notify one (by default) or all threads waiting on the synchronization object

parallel\Sync::__invoke

Synchronization

说明

public parallel\Sync::__invoke ( callable $critical )

Shall exclusively enter into the critical code