Backend Development 15 min read

PHP Multi‑Process Development: Processes, Signals, and pcntl Functions

This article provides a comprehensive guide to PHP multi‑process development on Linux, covering basic shell commands, ELF file types, terminal concepts, process states, orphan and zombie processes, process groups and sessions, signal handling, and practical pcntl/posix code examples for forking, daemonizing, and managing child processes.

php中文网 Courses
php中文网 Courses
php中文网 Courses
PHP Multi‑Process Development: Processes, Signals, and pcntl Functions

PHP Multi‑Process Development

This section introduces several useful Linux commands for process inspection, such as echo $$ , strace -s 65500 -p <pid> , kill -s 10 <pid> , pstree -ap , and ps -ajx , and explains the meaning of common ps fields (PPID, PID, PGID, SID, TTY, STAT, UID, COMMAND).

What is a program? In Linux a program is an executable file stored in ELF (Executable Linkable Format) without a file extension. ELF files are divided into four types: EXEC (executable), REL (relocatable/static library), Shared Object File, and core dump. Tools like objdump or readelf can inspect ELF files.

What is a terminal? Physical terminals (tty) are represented by /dev/ttyX , while pseudo‑terminals (pts) are created via TCP/IP (e.g., SSH) and appear as /dev/pts/X . Standard file descriptors are 0 (stdin), 1 (stdout), and 2 (stderr).

What is a process? A process ends when it reaches the last statement, encounters return , calls exit() , crashes, or receives a termination signal. After termination the process remains in memory as a zombie until the parent calls pcntl_wait() or pcntl_waitpid() to reap it.

Orphan and zombie processes – Orphans are adopted by the init process (PID 1) when the parent exits. Zombies are child processes that have terminated but not been reaped by the parent.

Process groups and sessions – A process group has a single group leader (PID = PGID). All processes in a group exit before the group disappears; view with ps -ajx . Multiple groups form a session, created with setsid() . The session leader cannot call setsid() again.

Signals – Signals are a form of inter‑process communication. Common usage includes kill -9 <pid> (SIGKILL). Supported signals are 1‑31 (no 32, 33). Sources of signals: keyboard (Ctrl+C → SIGINT), terminal close (SIGHUP), hardware, kill command, or software (e.g., SIGPIPE). When a process receives a signal it can: (1) follow the default action, (2) ignore it with pcntl_signal($signo, SIG_IGN) , or (3) handle it with a custom callback via pcntl_signal() . Signal handlers are inherited by child processes created with fork() .

POSIX functions

<code>posix_getpid();            // get current PID
posix_getppid();           // get parent PID
posix_getpgid($pid);      // get process group ID
posix_getsid($pid);       // get session ID
posix_getuid();           // get user ID
posix_getgid();           // get group ID
posix_kill($pid, $sig);   // send signal</code>

PCNTL functions

<code>pcntl_fork();                         // create child process
pcntl_signal($signo, $handler);       // install signal handler
pcntl_signal_dispatch();             // dispatch pending signals
pcntl_sigprocmask($how, $set);       // block/unblock signals
pcntl_wait($status);                 // wait for any child
pcntl_waitpid($pid, $status);        // wait for specific child
pcntl_wifexited($status);            // child exited normally?
pcntl_wexitstatus($status);          // exit code
pcntl_wifsignaled($status);          // terminated by signal?
pcntl_wtermsig($status);             // which signal
pcntl_wifstopped($status);           // stopped?
pcntl_wstopsig($status);             // which signal stopped it
pcntl_errno(); pcntl_strerror();    // error handling</code>

Example: Forking three child processes that share a single Redis connection

<code>&lt;?php
$o_redis = new Redis();
$o_redis->connect('127.0.0.1', 6379);
for ($i = 1; $i <= 3; $i++) {
    $pid = pcntl_fork();
    if ($pid == 0) {
        while (true) { sleep(1); }
    }
}
while (true) { sleep(1); }
?&gt;</code>

All four processes (parent + three children) share the same Redis connection, which can cause command interleaving; the correct approach is to create a separate Redis connection per child or use a connection pool.

Creating a daemon process

<code>$pid = pcntl_fork();
if ($pid > 0) { exit(); }
elseif ($pid == 0) {
    if (posix_setsid() < 0) { exit(); }
    chdir('/');
    umask(0);
    fclose(STDIN); fclose(STDOUT); fclose(STDERR);
    echo "create success, pid = " . posix_getpid();
    while (true) { /* business logic */ }
}
</code>

Process title can be changed with cli_set_process_title() for both master and worker processes.

Signal handling example (blocking version)

<code>function signal_handler($signal) {
    switch ($signal) {
        case SIGTERM: echo "sigterm signal.\n"; break;
        case SIGUSR1: echo "sigusr1 signal.\n"; break;
        case SIGUSR2: echo "sigusr2 signal.\n"; break;
        default: echo "other signal.\n";
    }
}
pcntl_signal(SIGTERM, "signal_handler");
pcntl_signal(SIGUSR1, "signal_handler");
pcntl_signal(SIGUSR2, "signal_handler");
while (true) {
    posix_kill(posix_getpid(), SIGUSR1);
    posix_kill(posix_getpid(), SIGUSR2);
    pcntl_signal_dispatch();
    sleep(1);
}
</code>

Non‑blocking signal handling (PHP 7.1+)

<code>pcntl_async_signals(true);
// install handlers as above
while (true) {
    posix_kill(posix_getpid(), SIGUSR1);
    posix_kill(posix_getpid(), SIGUSR2);
    sleep(1);
}
</code>

Blocking a specific signal

<code>pcntl_sigprocmask(SIG_BLOCK, [SIGUSR1], $old);
// later
pcntl_sigprocmask(SIG_UNBLOCK, [SIGUSR1], $old);
</code>

The remainder of the original content consists of promotional material for a PHP live‑streaming class and can be ignored for the academic summary.

Backend DevelopmentMulti-ProcessUnixSignalspcntl
php中文网 Courses
Written by

php中文网 Courses

php中文网's platform for the latest courses and technical articles, helping PHP learners advance quickly.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.