Common IPC facilities, including channels, locks, shared memory, and signals.
You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Go to file
Noccy c855f92ecd Added __invoke() to SignalTrap and fixed phpunit xml 3 years ago
examples Added __invoke() to SignalTrap and fixed phpunit xml 3 years ago
src Added __invoke() to SignalTrap and fixed phpunit xml 3 years ago
tests Added MultiStreamChannel to handle multiple endpoints 5 years ago
.gitignore Semaphores fully implemented 5 years ago Removed the bus interop code for now 5 years ago
composer.json More examples and tweaks 5 years ago
phpunit.xml Added __invoke() to SignalTrap and fixed phpunit xml 3 years ago


This is a one-size-fits-all IPC library to facilitate communication between threads and processes.

For complete examples, see the examples directory in the source tree.


Asynchronous signals are automatically enabled if supported. Otherwise, the pcntl_signal_dispatch() method must be frequently called from your main loop. You can test for this using the SIGNALS_ASYNC constant:


Signal handlers

Signal handlers allow for multiple listeners, with any one of them being able to prevent the signal from bubbling up.

$handler = new SignalHandler(SIGUSR1);

$handler->addHandler(function () {
    // Handle SIGUSR1, return true to stop bubbling
    return true;

You can also handle as well as fire signals using the Signal class:

$signal = new Signal(SIGUSR1);
$signal->setHandler(function () {
    // Handle SIGUSR1

// Dispatch the signal to ourselves
(new Signal(SIGUSR1))->dispatch($pid);

Signal traps

Traps are used in the main loop to break on signals

$trap = new SignalTrap(SIGINT);

while (!$trap->isTrapped()) {
    // ...


Timers fire asynchronously at fixed 1 second intervals. It requires signals to be processed; see above.

// Once every second...
$timer = new Timer(function () {
    echo ".";

File locks

File locks uses a shared file as a resource for locking.

// Creating the lock will not acquire it
$lock = new FileLock(__FILE__);

if (!$lock->acquire()) {
    echo "fail!\n";
} else {

SysV wrappers

All these wrappers depend on a KeyInterface being passed to the constructor. This is usually an instance of a FileKey, created as such:

$key = new FileKey(__FILE__);

The key has a project identifier that starts at chr(0), or "\0". To increase this identifier, and thus point to another segment, just clone it.

$key2 = clone $key1;


Semaphores are created with a key and a max count.

$key = new FileKey(__FILE__);
$sem = new Semaphore($key, 2);

$sem->allocate(); // -> true
$sem->allocate(); // -> true
$sem->allocate(); // -> false



A mutex is a semaphore with a max count of 1.

$key = new FileKey(__FILE__);
$mutex = new Mutex($key);

$mutex->allocate(); // -> true
$mutex->allocate(); // -> false


Message Queues

$key = new FileKey(__FILE__);
$msgq = new Queue($key);

$msgq->send(1, [ "Some data", [ "format"=>"foo" ]]);

$data = $msgq->receive(1, $type);


Shared Memory

Shared memory using SharedData supports integrity checking when setting, using the third parameter to set().

$key = new FileKey(__FILE__);
$shm = new SharedData($key);

do {
    $counter = $shm->get("counter") + 1;
} while (!$shm->set("counter", $counter, true));


The SharedMemory class is a simple integer-indexed array

$key = new FileKey(__FILE__);
$shm = new SharedMemory($key);

$shm[0] = 42;    




Channels are essentially connected pipes. A channel can be created with a stream resource, or through the createPair() factory method.

[ $ch1, $ch2 ] = StreamChannel::createPair();
$rcvd = $ch2->receive();


The MultiStreamChannel lets you connect multiple clients to a single master channel.

$master = new MultiStreamChannel();

$ch1 = $master->createClient();
$ch2 = $master->createClient();
$rcvd = $ch2->receive();