PHPackages                             jenner/simple\_fork - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. jenner/simple\_fork

ActivePackage[Utility &amp; Helpers](/categories/utility)

jenner/simple\_fork
===================

simple multi process manager based on pcntl

1.2.2(9y ago)227328.3k↓45.7%58[3 issues](https://github.com/huyanping/simple-fork-php/issues)[2 PRs](https://github.com/huyanping/simple-fork-php/pulls)11MITPHPPHP &gt;=5.3.0

Since Aug 13Pushed 5y ago9 watchersCompare

[ Source](https://github.com/huyanping/simple-fork-php)[ Packagist](https://packagist.org/packages/jenner/simple_fork)[ RSS](/packages/jenner-simple-fork/feed)WikiDiscussions master Synced 1w ago

READMEChangelog (10)DependenciesVersions (15)Used By (11)

SimpleFork
==========

[](#simplefork)

[![Join the chat at https://gitter.im/huyanping/simple-fork-php](https://camo.githubusercontent.com/b8d3598aef7eef9de7b3ed54faa3b5db07942ae7938733c76ce1c8339ee1b114/68747470733a2f2f6261646765732e6769747465722e696d2f687579616e70696e672f73696d706c652d666f726b2d7068702e737667)](https://gitter.im/huyanping/simple-fork-php?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)[![Latest Stable Version](https://camo.githubusercontent.com/2faaf5f68eb57efedc96e91bc482c630c908d8995b9bc69014a8171265212a40/68747470733a2f2f706f7365722e707567782e6f72672f6a656e6e65722f73696d706c655f666f726b2f762f737461626c65)](https://packagist.org/packages/jenner/simple_fork)[![Total Downloads](https://camo.githubusercontent.com/59be904c967f9864736128e5da3c2c4d7866e5babd900cc14d83e20fc4fd74e3/68747470733a2f2f706f7365722e707567782e6f72672f6a656e6e65722f73696d706c655f666f726b2f646f776e6c6f616473)](https://packagist.org/packages/jenner/simple_fork)[![Latest Unstable Version](https://camo.githubusercontent.com/dfba856ba249a20ea9c37a92ed0015a9bea4f6844767d9d909ce1ef08cde1e3f/68747470733a2f2f706f7365722e707567782e6f72672f6a656e6e65722f73696d706c655f666f726b2f762f756e737461626c65)](https://packagist.org/packages/jenner/simple_fork)[![License](https://camo.githubusercontent.com/fd698cf00873e80697ad49880daa3e9f934748594ef2f19d0d6bec95bfa7e0f6/68747470733a2f2f706f7365722e707567782e6f72672f6a656e6e65722f73696d706c655f666f726b2f6c6963656e7365)](https://packagist.org/packages/jenner/simple_fork)[![travis](https://camo.githubusercontent.com/1b742994289ac49950a4d515c032f00eb0010b9e2dcf8cb93444754208b26d19/68747470733a2f2f7472617669732d63692e6f72672f687579616e70696e672f73696d706c652d666f726b2d7068702e737667)](https://travis-ci.org/huyanping/simple-fork-php)[![Scrutinizer Code Quality](https://camo.githubusercontent.com/d23373c0a1614c34d0e856226edab4610e58ee8dff99b03704592e5fbfc7a363/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f687579616e70696e672f73696d706c652d666f726b2d7068702f6261646765732f7175616c6974792d73636f72652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/huyanping/simple-fork-php/?branch=master)[![Code Coverage](https://camo.githubusercontent.com/63d3f91121cf0254db82caf7a73f836bffcc18196fdd278dc6dd66c53f0035d2/68747470733a2f2f7363727574696e697a65722d63692e636f6d2f672f687579616e70696e672f73696d706c652d666f726b2d7068702f6261646765732f636f7665726167652e706e673f623d6d6173746572)](https://scrutinizer-ci.com/g/huyanping/simple-fork-php/?branch=master)

[中文README.MD](https://github.com/huyanping/simple-fork-php/blob/master/README.ZH.MD)
Simple Fork Framework is based on PCNTL extension, the interfaces are like `Thread` and `Runnable` in Java.

Why SimpleFork
--------------

[](#why-simplefork)

Writing Multi-Processes programs are hard for freshman. You must consider that how to recover zombie processes, interprocess communication, especially handle the process signal. SimpleFork framework provide several interfaces which like Java `Thread` and solutions in process pool, sync and IPC. You do not need to care about how to control multi-processes.

Require
-------

[](#require)

```
composer require jenner/simple_fork
```

Or

```
require '/path/to/simple-fork-php/autoload.php'
```

Dependencies
------------

[](#dependencies)

must

- php &gt; 5.3.0
- ext-pcntl process control

optional

- ext-sysvmsg message queue
- ext-sysvsem semaphore
- ext-sysvshm shared memory
- ext-redis redis cache and redis message queue

Property
--------

[](#property)

- Process Pool and Fixed Pool
- Recover zombie process automatically
- shared memory, system v message queue, semaphore lock, file lock, redis cache, redis queue
- Three ways to make Process: extends Process, implements Runnable or create a process object with a callback function
- You can get the status of sub process
- You can stop any processes if you want, or just shutdown all processes
- You can reload the processes by reload() method, then the processes will exit and start new processes instead.

Process Pool
------------

[](#process-pool)

There are two pool you can use when you have more than one process or task to manage:Pool and FixedPool.

- Pool: you can execute different processes in one Pool object. and call the `wait` method to wait for all the sub processes exiting (or just do something else, but do not forget to call the `wait` method)
- ParallelPool: it will keep the sub processes count, you should not init any socket connection before the FixedPool start(share socket connection is dangerous in multi processes).This class has a method `reload` which can reload all the sub processes. When you call `reload` method, the master will start new N processes and shutdown the old ones.
- SinglePool: no matter how many processes you execute, it will always keep one process starting and start another after it stopped.
- FixedPool: no matter how many processes you execute, it will always keep N processes starting and start another after it stopped. the active processes' count is less then N+1 forever.

Notice
------

[](#notice)

- Remember that you should call the `Process::dispatchSignal` method to call call signal handlers for pending signals.
- It is not recommend that adding `declare(ticks=n);` at the start of program to handle the pending signals.
- A better way to handle the single is that calling `pcntl_signal_dispatch`instead of `declare` which is more is a waste of CPU resources
- If the sub processes exit continually and quickly, you should set `n` to a small integer, else set a big one to save the CPU time.
- If you want to register signal handler in the master process, the child will inherit the handler.
- If you want to register signal handler in the child process before it start, you can call the `Process::registerSignalHandler` method. `start`method of the sub process is called, it will register the signal handler automatically.

Examples
--------

[](#examples)

More examples in \[examples\]( examples) dictionary
**A simple example.**

```
class TestRunnable implements \Jenner\SimpleFork\Runnable{

    /**
     * Entrance
     * @return mixed
     */
    public function run()
    {
        echo "I am a sub process" . PHP_EOL;
    }
}

$process = new \Jenner\SimpleFork\Process(new TestRunnable());
$process->start();
$process->wait();
```

**A process using callback**

```
$process = new \Jenner\SimpleFork\Process(function(){
    for($i=0; $istart();
$process->wait();
```

**Process communication using shared memory**

```
class Producer extends \Jenner\SimpleFork\Process{
    public function run(){
        $cache = new \Jenner\SimpleFork\Cache\SharedMemory();
        //$cache = new \Jenner\SimpleFork\Cache\RedisCache();
        for($i = 0; $iset($i, $i);
            echo "set {$i} : {$i}" . PHH_EOL;
        }
    }
}

class Worker extends \Jenner\SimpleFork\Process{
    public function run(){
        sleep(5);
        $cache = new \Jenner\SimpleFork\Cache\SharedMemory();
        //$cache = new \Jenner\SimpleFork\Cache\RedisCache();
        for($i=0; $iget($i) . PHP_EOL;
        }
    }
}

$producer = new Producer();

$worker = new Worker();

$pool = new \Jenner\SimpleFork\Pool();
$pool->execute($producer);
$pool->execute($worker);
$pool->wait();
```

**Process communication using system v message queue**

```
class Producer extends \Jenner\SimpleFork\Process
{
    public function run()
    {
        $queue = new \Jenner\SimpleFork\Queue\SystemVMessageQueue();
        //$queue = new \Jenner\SimpleFork\Queue\RedisQueue();
        for ($i = 0; $i < 10; $i++) {
            echo getmypid() . PHP_EOL;
            $queue->put($i);
        }
    }
}

class Worker extends \Jenner\SimpleFork\Process
{
    public function run()
    {
        sleep(5);
        $queue = new \Jenner\SimpleFork\Queue\SystemVMessageQueue();
        //$queue = new \Jenner\SimpleFork\Queue\RedisQueue();
        for ($i = 0; $i < 10; $i++) {
            $res = $queue->get();
            echo getmypid() . ' = ' . $i . PHP_EOL;
            var_dump($res);
        }
    }
}

$producer = new Producer();

$worker = new Worker();

$pool = new \Jenner\SimpleFork\Pool();
$pool->execute($producer);
$pool->execute($worker);
$pool->wait();
```

**Process communication using Semaphore lock**

```
class TestRunnable implements \Jenner\SimpleFork\Runnable
{

    /**
     * @var \Jenner\SimpleFork\Lock\LockInterface
     */
    protected $sem;

    public function __construct()
    {
        $this->sem = \Jenner\SimpleFork\Lock\Semaphore::create("test");
        //$this->sem = \Jenner\SimpleFork\Lock\FileLock::create("/tmp/test.lock");
    }

    /**
     * @return mixed
     */
    public function run()
    {
        for ($i = 0; $i < 20; $i++) {
            $this->sem->acquire();
            echo "my turn: {$i} " . getmypid() . PHP_EOL;
            $this->sem->release();
            sleep(1);
        }
    }
}

$pool = new \Jenner\SimpleFork\Pool();
$pool->execute(new \Jenner\SimpleFork\Process(new TestRunnable()));
$pool->execute(new \Jenner\SimpleFork\Process(new TestRunnable()));

$pool->wait();
```

**Process pool to manage processes**

```
$pool = new \Jenner\SimpleFork\Pool();
$pool->execute(new \Jenner\SimpleFork\Process(new TestRunnable()));
$pool->execute(new \Jenner\SimpleFork\Process(new TestRunnable()));
$pool->execute(new \Jenner\SimpleFork\Process(new TestRunnable()));

$pool->wait();
```

**ParallelPool to manage processes**

```
$fixed_pool = new \Jenner\SimpleFork\ParallelPool(new TestRunnable(), 10);
$fixed_pool->start();
$fixed_pool->keep(true);
```

**FixedPool to manage processes**

```
$pool = new \Jenner\SimpleFork\FixedPool(2);
$pool->execute(new \Jenner\SimpleFork\Process(new TestRunnable()));
$pool->execute(new \Jenner\SimpleFork\Process(new TestRunnable()));
$pool->execute(new \Jenner\SimpleFork\Process(new TestRunnable()));

$pool->wait();
```

**SinglePool to manage processes**

```
$pool = new \Jenner\SimpleFork\SinglePool();
$pool->execute(new \Jenner\SimpleFork\Process(new TestRunnable()));
$pool->execute(new \Jenner\SimpleFork\Process(new TestRunnable()));
$pool->execute(new \Jenner\SimpleFork\Process(new TestRunnable()));

$pool->wait();
```

###  Health Score

45

—

FairBetter than 91% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity54

Moderate usage in the ecosystem

Community28

Small or concentrated contributor base

Maturity66

Established project with proven stability

 Bus Factor1

Top contributor holds 99.8% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~45 days

Recently: every ~122 days

Total

14

Last Release

3367d ago

Major Versions

0.7 → 1.0.02015-10-28

### Community

Maintainers

![](https://www.gravatar.com/avatar/8d132b55d12cd603f8cce9c152999e2b3f98748d56fe8a21adf62d5830d88d87?d=identicon)[huyanping](/maintainers/huyanping)

---

Top Contributors

[![white-poto](https://avatars.githubusercontent.com/u/4362540?v=4)](https://github.com/white-poto "white-poto (520 commits)")[![gitter-badger](https://avatars.githubusercontent.com/u/8518239?v=4)](https://github.com/gitter-badger "gitter-badger (1 commits)")

---

Tags

multi-processpcntlprocess-communicationprocess-managerprocess-poolredis-cacheredis-queueforkprocess managerfork managerprocess ipc

### Embed Badge

![Health badge](/badges/jenner-simple-fork/health.svg)

```
[![Health](https://phpackages.com/badges/jenner-simple-fork/health.svg)](https://phpackages.com/packages/jenner-simple-fork)
```

###  Alternatives

[spatie/fork

A lightweight solution for running code concurrently in PHP

1.0k3.0M60](/packages/spatie-fork)[supervisorphp/supervisor

PHP library for managing Supervisor through XML-RPC API

2492.1M17](/packages/supervisorphp-supervisor)[duncan3dc/fork-helper

Simple class to fork processes in PHP and allow multi-threading

81566.2k4](/packages/duncan3dc-fork-helper)[arara/process

Provides a better API to work with processes on Unix-like systems

16862.4k2](/packages/arara-process)[polonskiy/phproutine

Goroutines in PHP

60124.2k](/packages/polonskiy-phproutine)[lifo/php-ipc

Simple PHP Inter Process Communication (IPC) library

285.6k](/packages/lifo-php-ipc)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
