parallel

目次

The parallel\Runtime class

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.

警告

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.

注意:

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()
public __construct(string $bootstrap)
/* Execute */
public Futurenull run(Closure $task)
public Futurenull run(Closure $task, array $argv)
/* Join */
public void close()
public void kill()
}

The parallel\Future class

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()
/* State */
public bool cancelled()
public bool done()
/* Cancellation */
public bool cancel()
}

The parallel\Channel class

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()
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()
public void send(mixed $value)
/* Closing */
public void close()
/* Constant for Infinitely Buffered */
const Infinite;
}

The parallel\Events class

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 parallel\Events\Eventnull poll()
}

The parallel\Events\Input class

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.

注意:

When a parallel\Events object performs a write, the target is removed from the input object as if 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()
}

The parallel\Events\Event class

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;
}

The parallel\Events\Event\Type class

クラス概要

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;
}

The parallel\Sync class

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()
public __construct(scalar $value)
/* Access */
public scalar get()
public set(scalar $value)
/* Synchronization */
public wait()
public notify(bool $all = ?)
public __invoke(callable $critical)
}