PHPackages                             maksimovic/simple-fork-php - 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. maksimovic/simple-fork-php

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

maksimovic/simple-fork-php
==========================

simple multi process manager based on pcntl

2.0.5(3mo ago)234.1k↓35.5%MITPHPPHP ^7.2 | ^8.0CI passing

Since Aug 13Pushed 3mo ago1 watchersCompare

[ Source](https://github.com/maksimovic/simple-fork-php)[ Packagist](https://packagist.org/packages/maksimovic/simple-fork-php)[ RSS](/packages/maksimovic-simple-fork-php/feed)WikiDiscussions master Synced yesterday

READMEChangelog (5)Dependencies (2)Versions (24)Used By (0)

SimpleFork
==========

[](#simplefork)

This is a fork of `jenner/simple_fork` compatible with these PHP versions:

- 7.2
- 7.3
- 7.4
- 8.0
- 8.1
- 8.2
- 8.3
- 8.4
- 8.5

[![codecov](https://camo.githubusercontent.com/2fd257c65d34ea4c279eb7749aa57598603e179dc525b97a57dafeccc957869a/68747470733a2f2f636f6465636f762e696f2f6769746875622f6d616b73696d6f7669632f73696d706c652d666f726b2d7068702f67726170682f62616467652e7376673f746f6b656e3d396b5a6b493345614776)](https://codecov.io/github/maksimovic/simple-fork-php)[![build status](https://github.com/maksimovic/simple-fork-php/actions/workflows/ci.yml/badge.svg)](https://github.com/maksimovic/simple-fork-php/actions/workflows/ci.yml/badge.svg)

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 maksimovic/simple-fork-php
```

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

[](#dependencies)

must

- php &gt;= 7.2
- 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)

**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

54

—

FairBetter than 96% of packages

Maintenance80

Actively maintained with recent releases

Popularity31

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity78

Established project with proven stability

 Bus Factor1

Top contributor holds 92.7% 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 ~214 days

Recently: every ~232 days

Total

19

Last Release

108d ago

Major Versions

0.7 → 1.0.02015-10-28

1.2.2 → 2.0.02023-08-29

PHP version history (2 changes)0.1PHP &gt;=5.3.0

2.0.0PHP ^7.2 | ^8.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/d43e10a649dca578689bc02aa4089e26c0d26b1a2f3640dda458973e55adcf10?d=identicon)[maksimovic](/maintainers/maksimovic)

---

Top Contributors

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

---

Tags

forkprocess managerfork managerprocess ipc

###  Code Quality

TestsPHPUnit

### Embed Badge

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

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

###  Alternatives

[jenner/simple_fork

simple multi process manager based on pcntl

233333.6k15](/packages/jenner-simple-fork)[spatie/fork

A lightweight solution for running code concurrently in PHP

1.0k3.2M68](/packages/spatie-fork)[supervisorphp/supervisor

PHP library for managing Supervisor through XML-RPC API

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

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

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

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

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

Goroutines in PHP

60126.0k](/packages/polonskiy-phproutine)

PHPackages © 2026

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