1
0
mirror of https://github.com/danog/parallel.git synced 2025-01-22 22:11:11 +01:00

Update examples in README

This commit is contained in:
coderstephen 2015-08-24 13:56:30 -05:00
parent d90c0aa25b
commit eaafe93761

View File

@ -18,34 +18,58 @@ A few benchmarks are provided for analysis and study. Can be used to back up imp
## Documentation ## Documentation
Concurrent can use either process forking or true threading to parallelize execution. Threading provides better performance and is compatible with Unix and Windows but requires ZTS (Zend thread-safe) PHP, while forking has no external dependencies but is only compatible with Unix systems. If your environment works meets neither of these requirements, this library won't work. Concurrent can use either process forking or true threading to parallelize execution. Threading provides better performance and is compatible with Unix and Windows but requires ZTS (Zend thread-safe) PHP, while forking has no external dependencies but is only compatible with Unix systems. If your environment works meets neither of these requirements, this library won't work.
### Contexts ### Threads
Concurrent provides a generic interface for working with parallel tasks called "contexts". All contexts are capable of being executed in parallel from the main program code. Each context is assigned a closure to execute when it is created, and the returned value is passed back to the parent context. Concurrent goes for a "shared-nothing" architecture, so any variables inside the closure are local to that context and can store any non-safe data. Threading is a cross-platform concurrency method that is fast and memory efficient. Thread contexts take advantage of an operating system's multi-threading capabilities to run code in parallel. A spawned thread will run completely parallel to the parent thread, each with its own environment. Each thread is assigned a closure to execute when it is created, and the returned value is passed back to the parent thread. Concurrent goes for a "shared-nothing" architecture, so any variables inside the closure are local to that thread and can store any non-safe data.
You can wait for a context to close by calling `join()`. Joining does not block the parent context and will asynchronously wait for the child context to finish before resolving. You can spawn a new thread with the `Thread::spawn()` method:
```php ```php
use Icicle\Concurrent\Threading\ThreadContext; use Icicle\Concurrent\Threading\Thread;
use Icicle\Coroutine; use Icicle\Coroutine;
use Icicle\Loop; use Icicle\Loop;
Coroutine\create(function () { Coroutine\create(function () {
$thread = new ThreadContext(function () { $thread = Thread::spawn(function () {
print "Hello, World!\n"; print "Hello, World!\n";
}); });
$thread->start();
yield $thread->join(); yield $thread->join();
}); });
Loop\run(); Loop\run();
``` ```
You can wait for a thread to finish by calling `join()`. Joining does not block the parent thread and will asynchronously wait for the child thread to finish before resolving.
### Forks
For Unix-like systems, you can create parallel execution using fork contexts. Though not as efficient as multi-threading, in some cases forking can take better advantage of some multi-core processors than threads. Fork contexts use the `pcntl_fork()` function to create a copy of the current process and run alternate code inside the new process.
Spawning and controlling forks are quite similar to creating threads. To spawn a new fork, use the `Fork::spawn()` method:
```php
use Icicle\Concurrent\Forking\Fork;
use Icicle\Coroutine;
use Icicle\Loop;
Coroutine\create(function () {
$fork = Fork::spawn(function () {
print "Hello, World!\n";
});
yield $fork->join();
});
Loop\run();
```
Calling `join()` on a fork will asynchronously wait for the forked process to terminate, similar to the `pcntl_wait()` function.
#### Synchronization with channels #### Synchronization with channels
Contexts wouldn't be very useful if they couldn't be given any data to work on. The recommended way to share data between contexts is with a `Channel`. A channel is a low-level abstraction over local, non-blocking sockets, which can be used to pass messages and objects between two contexts. Channels are non-blocking and do not require locking. For example: Threads and forks wouldn't be very useful if they couldn't be given any data to work on. The recommended way to share data between contexts is with a `Channel`. A channel is a low-level abstraction over local, non-blocking sockets, which can be used to pass messages and objects between two contexts. Channels are non-blocking and do not require locking. For example:
```php ```php
use Icicle\Concurrent\Sync\Channel; use Icicle\Concurrent\Sync\Channel;
use Icicle\Concurrent\Threading\ThreadContext; use Icicle\Concurrent\Threading\Thread;
use Icicle\Coroutine; use Icicle\Coroutine;
use Icicle\Loop; use Icicle\Loop;
@ -53,12 +77,11 @@ Coroutine\create(function () {
list($socketA, $socketB) = Channel::createSocketPair(); list($socketA, $socketB) = Channel::createSocketPair();
$channel = new Channel($socketA); $channel = new Channel($socketA);
$thread = new ThreadContext(function ($socketB) { $thread = Thread::spawn(function ($socketB) {
$channel = new Channel($socketB); $channel = new Channel($socketB);
yield $channel->send("Hello!"); yield $channel->send("Hello!");
}, $socketB); }, $socketB);
$thread->start();
$message = (yield $channel->receive()); $message = (yield $channel->receive());
yield $thread->join(); yield $thread->join();
}); });
@ -69,11 +92,5 @@ Loop\run();
### Synchronization with parcels ### Synchronization with parcels
Parcels are shared containers that allow you to store context-safe data inside a shared location so that it can be accessed by multiple contexts. To prevent race conditions, you still need to access a parcel's data exclusively, but Concurrent allows you to acquire a lock on a parcel asynchronously without blocking the context execution, unlike traditional mutexes. Parcels are shared containers that allow you to store context-safe data inside a shared location so that it can be accessed by multiple contexts. To prevent race conditions, you still need to access a parcel's data exclusively, but Concurrent allows you to acquire a lock on a parcel asynchronously without blocking the context execution, unlike traditional mutexes.
### Threading
Threading is a cross-platform concurrency method that is fast and memory efficient. Thread contexts take advantage of an operating system's multi-threading capabilities to run code in parallel.
### Forking
For Unix-like systems, you can create parallel execution using fork contexts. Though not as efficient as multi-threading, in some cases forking can take better advantage of some multi-core processors than threads. Fork contexts use the `pcntl_fork()` function to create a copy of the current process and run alternate code inside the new process.
## License ## License
All documentation and source code is licensed under the Apache License, Version 2.0 (Apache-2.0). See the [LICENSE](LICENSE) file for details. All documentation and source code is licensed under the Apache License, Version 2.0 (Apache-2.0). See the [LICENSE](LICENSE) file for details.