noccylabs/ipc ============= 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. ## Signals 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: if (!SIGNALS_ASYNC) { pcntl_signal_dispatch(); } ### 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 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 { $lock->release(); } ## 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 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 $sem->release(); $mutex->destroy(); ### Mutexes 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 $mutex->release(); $mutex->destroy(); ### Message Queues $key = new FileKey(__FILE__); $msgq = new Queue($key); $msgq->send(1, [ "Some data", [ "format"=>"foo" ]]); $data = $msgq->receive(1, $type); $msgq->destroy(); ### 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)); $shm->destroy(); The `SharedMemory` class is a simple integer-indexed array $key = new FileKey(__FILE__); $shm = new SharedMemory($key); $shm[0] = 42; $shm->destroy(); ## Communication ### Channels Channels are essentially connected pipes. A channel can be created with a stream resource, or through the `createPair()` factory method. [ $ch1, $ch2 ] = StreamChannel::createPair(); $ch1->send($data); $rcvd = $ch2->receive(); ### MultiChannels The `MultiStreamChannel` lets you connect multiple clients to a single master channel. $master = new MultiStreamChannel(); $ch1 = $master->createClient(); $ch2 = $master->createClient(); $ch1->send($data); $rcvd = $ch2->receive();