PHP 多进程编程


多进程编程


正文

进程和线程的区别

进程是一个具有独立功能的程序,是关于某个数据集合的一次运行活动。换句话说就是,在系统调度多个cpu的时候,一个程序的基本单元。

进程有两个特性部分:资源所有权和调度执行。 资源所有权是指进程包括了进程运行所需要的内存空间、I/O等资源。 调度执行是指进程执行过程中间的执行路径,或者说程序的指令执行流。 这两个特性部分是可以分开的,分开后,拥有资料所有权的通常称为进程, 拥有执行代码的可分派部分的被称之为线程或轻量级进程。

线程有“执行的线索”的意思在里面,而进程在多线程环境中被定义为资源所有者,其还是会存储进程的进程控制块。

更多关于进程和线程的内容,看一下参考资料。

php编程常见的进程和线程

1、在web应用中,我们每次访问php,就建立一个PHP进程,当然也会建立至少一个PHP线程。

2、PHP使用pcntl来进行多进程编程

3、PHP中使用pthreads来进行多线程编程

4、nginx的每个进程只有一个线程,每个线程可以处理多个客户端的访问

5、php-fpm使用多进程模型,每个进程只有一个线程,每个线程只能处理一个客户端访问。

6、apache可能使用多进程模型,也可能使用多线程模型,取决于使用哪种SAPI.

PHP进程环境

php中的进程是以扩展的形式来完成。通过这些扩展,我们能够很轻松的完成进程的一系列动作。

pcntl扩展:主要的进程扩展,完成进程创建、程序执行、信号处理以及进程的中断等操作。
posix扩展:完成了posix兼容机通用api,如获取进程id,杀死进程等。
pthreads扩展:一组允许用户在 PHP 中使用多线程技术的面向对象的 API,它提供了创建多线程应用所需的全套工具。
sysvmsg扩展:实现system v方式的进程间通信之消息队列。
sysvsem扩展:实现system v方式的信号量。
sysvshm扩展:实现system v方式的共享内存。
sockets扩展:实现socket通信。

这些扩展只能在linux/mac中使用,window下是不支持。最后建议php版本为5.5+。

pcntl扩展: PHP 手册 函数参考 进程控制扩展 进程控制 https://www.php.net/manual/zh/book.pcntl.php

posix扩展: PHP 手册 函数参考 进程控制扩展 POSIX https://www.php.net/manual/zh/book.posix.php

pthreads扩展: PHP 手册 函数参考 进程控制扩展 pthreads https://www.php.net/manual/zh/book.pthreads.php

编程实例

说这么多进程线程的异同,而不实际操作是不会明白真正的异同和用途的。

我们看一下PHP中多进程编码的实例:

$selfPid = posix_getpid();
echo "self progress id:{$selfPid}\n";
$pid = pcntl_fork();
echo "fork pid:{$pid}\n";
if ( $pid == -1) {
    // 创建失败
    exit("fork progress error!\n");
} else if ($pid == 0) {
    // 子进程执行程序
    $pid = posix_getpid();
    $repeatNum = 3;
    for ( $i = 1; $i <= $repeatNum; $i++) {
        echo "({$pid})child progress is running! {$i} \n";
        $rand = rand(1,3);
        sleep($rand);
    }
    exit("({$pid})child progress end!\n");
} else {
    // 父进程执行程序
    echo "({$pid})parent progress is running!\n";
}
// 等待子进程结束
pcntl_wait($status);
echo "({$selfPid})main progress end!";

输出结果:

self progress pid:7
fork pid:9
(9)parent progress is running!
fork pid:0
(9)child progress is running! 1 
(9)child progress is running! 2 
(9)child progress is running! 3 
(9)child progress end!
(7)main progress end!

再看一个例子,队列消费者实现,你可能会说队列有一个消费者不就可以消费了吗,如果同一队列需要多个消费者呢,我们怎么开启和关闭这些消费者进程。

队列管理服务:

namespace rabbitMQ\controllers;

use yii;

class ConsumerController extends BaseController
{
    //项目根目录 , 如 dirname(__DIR__)
    private $root;
    
    //worker pidfile ,如 /data/log/rabbitMQ/Mail
    private $pidfile;
    
    //worker进程pid
    private $pids = [];

    //consumer
    private $consumer;
    
    //rabbitMQ全局配置 ,连接信息 [ip地址、端口、用户名、密码]
    private $setting = [];
    
    //worker对应queue,exchange,rooting绑定配置 , 如 ['CMail' => ['queue' => 'queue_mail', 'exchange' => 'async', 'routing' => 'mail']]
    private $bindSetting = [];
    
    //worker实例
    private $worker;
    
    public function initConsumer($consumer)
    {
        $this->consumer = ucfirst($consumer);

        $this->root = Yii::$app->params['root'];
        
        $this->pidfile = Yii::$app->params['pidfile_root'] . $this->consumer;
        
        $this->bindSetting = Yii::$app->params['C' . $this->consumer];

        $this->setting = Yii::$app->params['rabbitMQ'];

        $this->pids = file_exists($this->pidfile) ? 
            explode(',', file_get_contents($this->pidfile))
            : null;
    }

    /**
     * 启动consumer-worker
     */
    public function actionStart($consumer)
    {
        $this->initConsumer($consumer);

        $pid = pcntl_fork();

        if ($pid == -1) {
            die('could not fork');
        } else if ($pid) {
            // 主进程退出
            exit(0);
        } else {
            // 子进程运行
            // 使当前进程成为守护进程,返回回话id。负责我们已关闭运行这一程序的命令框,该程序就结束运行了,用守护进程可以使程序在后台运行。
            posix_setsid();

            // 当前进程 id 写入文件
            if (file_exists($this->pidfile)){
                file_put_contents($this->pidfile, ',' . posix_getpid(), FILE_APPEND);
            } else {
                file_put_contents($this->pidfile, posix_getpid());
            }

            $this->msgqueue();
        }
    }

    /**
     * 停止consumer-worker
     */
    public function actionStop($consumer)
    {
        $this->initConsumer($consumer);

        if (empty($this->pids)) {
            echo "\n" . 'worker not start' . "\n";
            exit();
        }

        foreach ($this->pids as $pid) 
        {
            // 结束指定进程
            posix_kill($pid, SIGTERM);
        }

        unlink($this->pidfile);

        echo "\n" . 'Stop Success' . "\n";
    }
    
    public function actionRestart($consumer)
    {
        $this->actionStop($consumer);
        sleep(2);
        $this->actionStart($consumer);
    }

    public function msgqueue()
    {
        $conn = new \AMQPConnection($this->setting);

        if (!$conn->connect()) {
            echo "\n" . 'Connect Failed' . "\n";
            exit();
        }

        echo "\n" . 'Connect Success' . "\n";

        $channel = new \AMQPChannel($conn);
        
        $ex = new \AMQPExchange($channel);
        $ex->setName($this->bindSetting['exchange']);
        $ex->setType(AMQP_EX_TYPE_DIRECT);
        $ex->setFlags(AMQP_DURABLE);
        $ex->declareExchange();
        
        $q = new \AMQPQueue($channel);

        $q->setName($this->bindSetting['queue']);
        $q->setFlags(AMQP_DURABLE);
        $q->declareQueue();
        $q->bind(
            $this->bindSetting['exchange'],
            $this->bindSetting['routing']
        );

        if (!file_exists($this->root . '/workers/' . $this->consumer . '.php')) {
            echo "\n" . 'worker does not exist' . "\n";
            exit();
        }

        $workerName = 'rabbitMQ\\workers\\' . $this->consumer;

        $this->worker = new $workerName();

        $channel->qos(0,1);
        $q->consume(array($this->worker, 'run'));

        $conn->disconnect();
    }
}

邮件消费推送服务:

namespace rabbitMQ\workers;

use Yii;

class Mail 
{
    /** @var  \common\logics\push\MailLogic $mailService */
    private $mailService;

    public function __construct()
    {
        $this->mailService = Yii::$container->get('mailService');
    }

    public function run($envelope, $queue)
    {
        $msg = $envelope->getBody();
        $this->mailService->sendMail($msg);
        Yii::$app->db->close();
        $queue->ack($envelope->getDeliveryTag());
    }
}

我们运行多次下面命令,生成多个这一队列的消费者:

php yii consumer/start mail

需要停止这些消费者,只需要运行一次就可以实现:

php yii consumer/stop mail

pthreads

pthreads 是一组允许用户在 PHP 中使用多线程技术的面向对象的 API。 它提供了创建多线程应用所需的全套工具。 通过使用 Thread, Worker 以及 Threaded 对象,PHP 应用可以创建、读取、写入以及执行多线程应用,并可以在多个线程之间进行同步控制。

注意:不可以在 web 服务器环境中使用 pthreads 扩展, PHP 多线程开发仅限于命令行模式的应用。

Threaded 对象: Threaded 对象提供支持 pthreads 操作的基本功能,包括同步方法以及其他对程序员很有帮助的接口。

Thread 对象: 通过继承 pthreads 中提供的 Thread 对象并实现 run 方法,用户可以创建自己的 Thread 对象。 只要线程上下文中持有某个 Thread 对象的引用,就可以读/写该对象的属性,也可以调用该对象的公有(public)或者受保护(protected)的方法。 当在创建 Thread 对象的上下文中调用该对象的 Thread::start() 方法时,pthreads 扩展会在另外的独立线程中执行该对象的 run 方法。 仅有创建 Thread 对象的线程/进程方可开始(start)或者加入(join)这个 Thread 对象。

Worker 对象: Worker 是有状态的线程对象,它在线程开始(通过调用 Thread::start() 方法)之后就可用, 除非代码中显式地关闭线程(通过调用 Worker::shutdown() 方法), 否则该对象在线程对象超出作用范围之后才会失效。 持有 Worker 对象引用的线程上下文可以向 Worker 中入栈(通过调用 Worker::stack() 方法)其他线程对象,Worker 对象将在独立线程中执行入栈对象的代码。 Woker 对象的 run 方法会在它的栈中入栈对象之前执行,这样就可以进行一些必需的资源初始化工作。

Pool 对象: Pool 对象是 Worker 线程对象池,可以用来在多个 Worker 对象之间分发 Threaded 对象, 这是最易用且高效的多线程编程方式。

Pool 是标准的 PHP 对象,它并没有继承 Threaded 类,所以不可以在多个线程上下文中共享同一个 Pool 对象。 

olatile 类是在 pthreads v3 中新增加的, 用来表示可变的 Threaded 类中的 Threaded 属性(默认情况下是不可变的)。 它也可以被用来在 Threaded 上下文中存储数组。

线程间同步: 由 pthreads 扩展创建的所有对象拥有内置的线程间同步机制, 和 Java 语言很类似, 使用 Threaded::wait() 和 Threaded::notify() 方法来实现线程间同步。 调用某一个对象的 Threaded::wait() 方法 会导致当前线程上下文进入等待状态, 等待另外一个线程上下文调用同一个对象的 Threaded::notify() 方法。 为 PHP Threaded 对象提供了强有力的线程间同步控制机制。

应用中会用在多线程场景中的对象都应该从 Threaded 类继承。 

数据存储: 一般来说,任何可以序列化的数据类型都可以作为 Threaded 对象的属性,它可以从持有该对象引用的任何线程上下文读/写。 并不是所有的数据都采用序列化方式存储,比如基本类型就是以其真实形态存储的。 对于不是 Threaded 派生的对象,例如复杂类型、数组以及对象等,都是序列化存储的,可以从持有 Threaded 对象引用的任何线程上下文中读取和写入, 区别就在于对于 Threaed 的派生对象,设置它的成员变量的过程是在独立线程上下文中执行的。 对于 Threaded 派生对象,在同一时间,不同的线程上下文都可以从该对象中读取到同样的数据。

静态成员: 当创建新的线程上下文(Thread 或 Worker 对象)的时候,静态成员会被拷贝到新的上下文中。出于安全考虑,资源类型以及包含内部状态的对象类型的静态成员会被置空。 实际上这个特性实现了类似线程本地存储的功能。举例说明,假设某个类拥有包含数据库连接信息以及数据库连接对象静态成员, 那么当新的线程上下文启动的时候,仅有数据库连接信息会被复制到新上下文中,而数据库连接对象并不会被复制。 所以,需要在新的上下文中根据复制过来的数据库连接基本信息来初始化数据库连接对象,新创建的数据库连接对象是独立的, 不影响在原上下文中的数据库连接对象。

Threaded — Threaded 类

    Threaded::chunk — 操作
    Threaded::count — 操作
    Threaded::extend — Runtime Manipulation
    Threaded::from — Creation
    Threaded::getTerminationInfo — 错误检测
    Threaded::isRunning — 状态检测
    Threaded::isTerminated — 状态检测
    Threaded::isWaiting — 状态检测
    Threaded::lock — 同步控制
    Threaded::merge — 操作
    Threaded::notify — 同步控制
    Threaded::notifyOne — Synchronization
    Threaded::pop — 操作
    Threaded::run — 执行
    Threaded::shift — Manipulation
    Threaded::synchronized — 同步控制
    Threaded::unlock — 同步控制
    Threaded::wait — Synchronization

Thread — Thread 类

    Thread::detach — 执行
    Thread::getCreatorId — 识别
    Thread::getCurrentThread — 识别
    Thread::getCurrentThreadId — 识别
    Thread::getThreadId — 识别
    Thread::globally — 执行
    Thread::isJoined — 状态监测
    Thread::isStarted — 状态检测
    Thread::join — 同步
    Thread::kill — 执行
    Thread::start — 执行

Worker — Worker 类

    Worker::collect — Collect references to completed tasks
    Worker::getStacked — 获取剩余的栈大小
    Worker::isShutdown — 状态检测
    Worker::isWorking — 状态检测
    Worker::shutdown — 关闭 Worker
    Worker::stack — 将要执行的任务入栈
    Worker::unstack — 将要执行的任务出栈

Collectable — The Collectable interface

    Collectable::isGarbage — Determine whether an object has been marked as garbage
    Collectable::setGarbage — Mark an object as garbage

Modifiers — 方法修饰符
Pool — Pool 类

    Pool::collect — 回收已完成任务的引用
    Pool::__construct — 创建新的 Worker 对象池
    Pool::resize — 改变 Pool 对象的可容纳 Worker 对象的数量
    Pool::shutdown — 停止所有的 Worker 对象
    Pool::submit — 提交对象以执行
    Pool::submitTo — 提交一个任务到特定的 Worker 以执行

Mutex — Mutex 类

    Mutex::create — 创建一个互斥量
    Mutex::destroy — 销毁互斥量
    Mutex::lock — 给互斥量加锁
    Mutex::trylock — 尝试给互斥量加锁
    Mutex::unlock — 释放互斥量上的锁

Cond — Cond 类

    Cond::broadcast — 广播条件变量
    Cond::create — 创建一个条件变量
    Cond::destroy — 销毁条件变量
    Cond::signal — 发送唤醒信号
    Cond::wait — 等待

Volatile — The Volatile class

附录

posix函数簇

预定义常量

    posix_access 系列常量
    posix_mknod 系列常量
    posix_setrlimit 系列常量

POSIX 函数

    posix_access — Determine accessibility of a file
    posix_ctermid — Get path name of controlling terminal
    posix_errno — 别名 posix_get_last_error
    posix_get_last_error — Retrieve the error number set by the last posix function that failed
    posix_getcwd — Pathname of current directory
    posix_getegid — Return the effective group ID of the current process
    posix_geteuid — Return the effective user ID of the current process
    posix_getgid — Return the real group ID of the current process
    posix_getgrgid — Return info about a group by group id
    posix_getgrnam — Return info about a group by name
    posix_getgroups — Return the group set of the current process
    posix_getlogin — Return login name
    posix_getpgid — Get process group id for job control
    posix_getpgrp — Return the current process group identifier
    posix_getpid — 返回当前进程 id
    posix_getppid — Return the parent process identifier
    posix_getpwnam — Return info about a user by username
    posix_getpwuid — Return info about a user by user id
    posix_getrlimit — Return info about system resource limits
    posix_getsid — Get the current sid of the process
    posix_getuid — Return the real user ID of the current process
    posix_initgroups — Calculate the group access list
    posix_isatty — Determine if a file descriptor is an interactive terminal
    posix_kill — Send a signal to a process
    posix_mkfifo — Create a fifo special file (a named pipe)
    posix_mknod — Create a special or ordinary file (POSIX.1)
    posix_setegid — Set the effective GID of the current process
    posix_seteuid — Set the effective UID of the current process
    posix_setgid — Set the GID of the current process
    posix_setpgid — Set process group id for job control
    posix_setrlimit — Set system resource limits
    posix_setsid — Make the current process a session leader
    posix_setuid — Set the UID of the current process
    posix_strerror — Retrieve the system error message associated with the given errno
    posix_times — Get process times
    posix_ttyname — Determine terminal device name
    posix_uname — Get system name
<?php

// Start of posix v.

/**
 * Send a signal to a process
 * @link https://php.net/manual/en/function.posix-kill.php
 * @param int $pid <p>
 * The process identifier.
 * </p>
 * @param int $sig <p>
 * One of the PCNTL signals constants.
 * </p>
 * @return bool <b>TRUE</b> on success or <b>FALSE</b> on failure.
 * @since 4.0
 * @since 5.0
 */
function posix_kill ($pid, $sig) {}

/**
 * Return the current process identifier
 * @link https://php.net/manual/en/function.posix-getpid.php
 * @return int the identifier, as an integer.
 * @since 4.0
 * @since 5.0
 */
function posix_getpid () {}

/**
 * Return the parent process identifier
 * @link https://php.net/manual/en/function.posix-getppid.php
 * @return int the identifier, as an integer.
 * @since 4.0
 * @since 5.0
 */
function posix_getppid () {}

/**
 * Return the real user ID of the current process
 * @link https://php.net/manual/en/function.posix-getuid.php
 * @return int the user id, as an integer
 * @since 4.0
 * @since 5.0
 */
function posix_getuid () {}

/**
 * Set the UID of the current process
 * @link https://php.net/manual/en/function.posix-setuid.php
 * @param int $uid <p>
 * The user id.
 * </p>
 * @return bool <b>TRUE</b> on success or <b>FALSE</b> on failure.
 * @since 4.0
 * @since 5.0
 */
function posix_setuid ($uid) {}

/**
 * Return the effective user ID of the current process
 * @link https://php.net/manual/en/function.posix-geteuid.php
 * @return int the user id, as an integer
 * @since 4.0
 * @since 5.0
 */
function posix_geteuid () {}

/**
 * Set the effective UID of the current process
 * @link https://php.net/manual/en/function.posix-seteuid.php
 * @param int $uid <p>
 * The user id.
 * </p>
 * @return bool <b>TRUE</b> on success or <b>FALSE</b> on failure.
 * @since 4.0.2
 * @since 5.0
 */
function posix_seteuid ($uid) {}

/**
 * Set system resource limits
 * @link https://php.net/manual/en/function.posix-setrlimit.php
 * @param int $resource <p>
 * The
 * {@link https://php.net/manual/en/posix.constants.setrlimit.php resource limit constant}
 * corresponding to the limit that is being set.
 * </p>
 * @param int $softlimit The soft limit, in whatever unit the resource limit requires, or POSIX_RLIMIT_INFINITY.
 * @param int $hardlimit The hard limit, in whatever unit the resource limit requires, or POSIX_RLIMIT_INFINITY.
 * @return bool Returns TRUE on success or FALSE on failure.
 * @since 7.0
 */
function posix_setrlimit ($resource, $softlimit, $hardlimit ) {}
/**
 * Return the real group ID of the current process
 * @link https://php.net/manual/en/function.posix-getgid.php
 * @return int the real group id, as an integer.
 * @since 4.0
 * @since 5.0
 */
function posix_getgid () {}

/**
 * Set the GID of the current process
 * @link https://php.net/manual/en/function.posix-setgid.php
 * @param int $gid <p>
 * The group id.
 * </p>
 * @return bool <b>TRUE</b> on success or <b>FALSE</b> on failure.
 * @since 4.0
 * @since 5.0
 */
function posix_setgid ($gid) {}

/**
 * Return the effective group ID of the current process
 * @link https://php.net/manual/en/function.posix-getegid.php
 * @return int an integer of the effective group ID.
 * @since 4.0
 * @since 5.0
 */
function posix_getegid () {}

/**
 * Set the effective GID of the current process
 * @link https://php.net/manual/en/function.posix-setegid.php
 * @param int $gid <p>
 * The group id.
 * </p>
 * @return bool <b>TRUE</b> on success or <b>FALSE</b> on failure.
 * @since 4.0.2
 * @since 5.0
 */
function posix_setegid ($gid) {}

/**
 * Return the group set of the current process
 * @link https://php.net/manual/en/function.posix-getgroups.php
 * @return array an array of integers containing the numeric group ids of the group
 * set of the current process.
 * @since 4.0
 * @since 5.0
 */
function posix_getgroups () {}

/**
 * Return login name
 * @link https://php.net/manual/en/function.posix-getlogin.php
 * @return string the login name of the user, as a string.
 * @since 4.0
 * @since 5.0
 */
function posix_getlogin () {}

/**
 * Return the current process group identifier
 * @link https://php.net/manual/en/function.posix-getpgrp.php
 * @return int the identifier, as an integer.
 * @since 4.0
 * @since 5.0
 */
function posix_getpgrp () {}

/**
 * Make the current process a session leader
 * @link https://php.net/manual/en/function.posix-setsid.php
 * @return int the session id, or -1 on errors.
 * @since 4.0
 * @since 5.0
 */
function posix_setsid () {}

/**
 * Set process group id for job control
 * @link https://php.net/manual/en/function.posix-setpgid.php
 * @param int $pid <p>
 * The process id.
 * </p>
 * @param int $pgid <p>
 * The process group id.
 * </p>
 * @return bool <b>TRUE</b> on success or <b>FALSE</b> on failure.
 * @since 4.0
 * @since 5.0
 */
function posix_setpgid ($pid, $pgid) {}

/**
 * Get process group id for job control
 * @link https://php.net/manual/en/function.posix-getpgid.php
 * @param int $pid <p>
 * The process id.
 * </p>
 * @return int the identifier, as an integer.
 * @since 4.0
 * @since 5.0
 */
function posix_getpgid ($pid) {}

/**
 * Get the current sid of the process
 * @link https://php.net/manual/en/function.posix-getsid.php
 * @param int $pid <p>
 * The process identifier. If set to 0, the current process is
 * assumed. If an invalid <i>pid</i> is
 * specified, then <b>FALSE</b> is returned and an error is set which
 * can be checked with <b>posix_get_last_error</b>.
 * </p>
 * @return int the identifier, as an integer.
 * @since 4.0
 * @since 5.0
 */
function posix_getsid ($pid) {}

/**
 * Get system name
 * @link https://php.net/manual/en/function.posix-uname.php
 * @return array a hash of strings with information about the
 * system. The indices of the hash are
 * sysname - operating system name (e.g. Linux)
 * nodename - system name (e.g. valiant)
 * release - operating system release (e.g. 2.2.10)
 * version - operating system version (e.g. #4 Tue Jul 20
 * 17:01:36 MEST 1999)
 * machine - system architecture (e.g. i586)
 * domainname - DNS domainname (e.g. example.com)
 * </p>
 * <p>
 * domainname is a GNU extension and not part of POSIX.1, so this
 * field is only available on GNU systems or when using the GNU
 * libc.
 * @since 4.0
 * @since 5.0
 */
function posix_uname () {}

/**
 * Get process times
 * @link https://php.net/manual/en/function.posix-times.php
 * @return array a hash of strings with information about the current
 * process CPU usage. The indices of the hash are:
 * ticks - the number of clock ticks that have elapsed since
 * reboot.
 * utime - user time used by the current process.
 * stime - system time used by the current process.
 * cutime - user time used by current process and children.
 * cstime - system time used by current process and children.
 * @since 4.0
 * @since 5.0
 */
function posix_times () {}

/**
 * Get path name of controlling terminal
 * @link https://php.net/manual/en/function.posix-ctermid.php
 * @return string Upon successful completion, returns string of the pathname to
 * the current controlling terminal. Otherwise <b>FALSE</b> is returned and errno
 * is set, which can be checked with <b>posix_get_last_error</b>.
 * @since 4.0
 * @since 5.0
 */
function posix_ctermid () {}

/**
 * Determine terminal device name
 * @link https://php.net/manual/en/function.posix-ttyname.php
 * @param int $fd <p>
 * The file descriptor.
 * </p>
 * @return string On success, returns a string of the absolute path of the
 * <i>fd</i>. On failure, returns <b>FALSE</b>
 * @since 4.0
 * @since 5.0
 */
function posix_ttyname ($fd) {}

/**
 * Determine if a file descriptor is an interactive terminal
 * @link https://php.net/manual/en/function.posix-isatty.php
 * @param mixed $fd <p>
 * The file descriptor, which is expected to be either a file resource or an integer.
 * An integer will be assumed to be a file descriptor that can be passed
 * directly to the underlying system call.<br />
 * In almost all cases, you will want to provide a file resource.
 * </p>
 * @return bool <b>TRUE</b> if <i>fd</i> is an open descriptor connected
 * to a terminal and <b>FALSE</b> otherwise.
 * @since 4.0
 * @since 5.0
 */
function posix_isatty ($fd) {}

/**
 * Pathname of current directory
 * @link https://php.net/manual/en/function.posix-getcwd.php
 * @return string a string of the absolute pathname on success.
 * On error, returns <b>FALSE</b> and sets errno which can be checked with
 * <b>posix_get_last_error</b>.
 * @since 4.0
 * @since 5.0
 */
function posix_getcwd () {}

/**
 * Create a fifo special file (a named pipe)
 * @link https://php.net/manual/en/function.posix-mkfifo.php
 * @param string $pathname <p>
 * Path to the FIFO file.
 * </p>
 * @param int $mode <p>
 * The second parameter <i>mode</i> has to be given in
 * octal notation (e.g. 0644). The permission of the newly created
 * FIFO also depends on the setting of the current
 * <b>umask</b>. The permissions of the created file are
 * (mode &#38;#38; ~umask).
 * </p>
 * @return bool <b>TRUE</b> on success or <b>FALSE</b> on failure.
 * @since 4.0
 * @since 5.0
 */
function posix_mkfifo ($pathname, $mode) {}

/**
 * Create a special or ordinary file (POSIX.1)
 * @link https://php.net/manual/en/function.posix-mknod.php
 * @param string $pathname <p>
 * The file to create
 * </p>
 * @param int $mode <p>
 * This parameter is constructed by a bitwise OR between file type (one of
 * the following constants: <b>POSIX_S_IFREG</b>,
 * <b>POSIX_S_IFCHR</b>, <b>POSIX_S_IFBLK</b>,
 * <b>POSIX_S_IFIFO</b> or
 * <b>POSIX_S_IFSOCK</b>) and permissions.
 * </p>
 * @param int $major [optional] <p>
 * The major device kernel identifier (required to pass when using
 * <b>S_IFCHR</b> or <b>S_IFBLK</b>).
 * </p>
 * @param int $minor [optional] <p>
 * The minor device kernel identifier.
 * </p>
 * @return bool <b>TRUE</b> on success or <b>FALSE</b> on failure.
 * @since 5.1.0
 */
function posix_mknod ($pathname, $mode, $major = 0, $minor = 0) {}

/**
 * Determine accessibility of a file
 * @link https://php.net/manual/en/function.posix-access.php
 * @param string $file <p>
 * The name of the file to be tested.
 * </p>
 * @param int $mode [optional] <p>
 * A mask consisting of one or more of <b>POSIX_F_OK</b>,
 * <b>POSIX_R_OK</b>, <b>POSIX_W_OK</b> and
 * <b>POSIX_X_OK</b>.
 * </p>
 * <p>
 * <b>POSIX_R_OK</b>, <b>POSIX_W_OK</b> and
 * <b>POSIX_X_OK</b> request checking whether the file
 * exists and has read, write and execute permissions, respectively.
 * <b>POSIX_F_OK</b> just requests checking for the
 * existence of the file.
 * </p>
 * @return bool <b>TRUE</b> on success or <b>FALSE</b> on failure.
 * @since 5.1.0
 */
function posix_access ($file, $mode = POSIX_F_OK) {}

/**
 * Return info about a group by name
 * @link https://php.net/manual/en/function.posix-getgrnam.php
 * @param string $name <p>The name of the group</p>
 * @return array The array elements returned are:
 * <table>
 * The group information array
 * <tr valign="top">
 * <td>Element</td>
 * <td>Description</td>
 * </tr>
 * <tr valign="top">
 * <td>name</td>
 * <td>
 * The name element contains the name of the group. This is
 * a short, usually less than 16 character "handle" of the
 * group, not the real, full name. This should be the same as
 * the <i>name</i> parameter used when
 * calling the function, and hence redundant.
 * </td>
 * </tr>
 * <tr valign="top">
 * <td>passwd</td>
 * <td>
 * The passwd element contains the group's password in an
 * encrypted format. Often, for example on a system employing
 * "shadow" passwords, an asterisk is returned instead.
 * </td>
 * </tr>
 * <tr valign="top">
 * <td>gid</td>
 * <td>
 * Group ID of the group in numeric form.
 * </td>
 * </tr>
 * <tr valign="top">
 * <td>members</td>
 * <td>
 * This consists of an array of
 * string's for all the members in the group.
 * </td>
 * </tr>
 * </table>
 * @since 4.0
 * @since 5.0
 */
function posix_getgrnam ($name) {}

/**
 * Return info about a group by group id
 * @link https://php.net/manual/en/function.posix-getgrgid.php
 * @param int $gid <p>
 * The group id.
 * </p>
 * @return array The array elements returned are:
 * <table>
 * The group information array
 * <tr valign="top">
 * <td>Element</td>
 * <td>Description</td>
 * </tr>
 * <tr valign="top">
 * <td>name</td>
 * <td>
 * The name element contains the name of the group. This is
 * a short, usually less than 16 character "handle" of the
 * group, not the real, full name.
 * </td>
 * </tr>
 * <tr valign="top">
 * <td>passwd</td>
 * <td>
 * The passwd element contains the group's password in an
 * encrypted format. Often, for example on a system employing
 * "shadow" passwords, an asterisk is returned instead.
 * </td>
 * </tr>
 * <tr valign="top">
 * <td>gid</td>
 * <td>
 * Group ID, should be the same as the
 * <i>gid</i> parameter used when calling the
 * function, and hence redundant.
 * </td>
 * </tr>
 * <tr valign="top">
 * <td>members</td>
 * <td>
 * This consists of an array of
 * string's for all the members in the group.
 * </td>
 * </tr>
 * </table>
 * @since 4.0
 * @since 5.0
 */
function posix_getgrgid ($gid) {}

/**
 * Return info about a user by username
 * @link https://php.net/manual/en/function.posix-getpwnam.php
 * @param string $username <p>
 * An alphanumeric username.
 * </p>
 * @return array On success an array with the following elements is returned, else
 * <b>FALSE</b> is returned:
 * <table>
 * The user information array
 * <tr valign="top">
 * <td>Element</td>
 * <td>Description</td>
 * </tr>
 * <tr valign="top">
 * <td>name</td>
 * <td>
 * The name element contains the username of the user. This is
 * a short, usually less than 16 character "handle" of the
 * user, not the real, full name. This should be the same as
 * the <i>username</i> parameter used when
 * calling the function, and hence redundant.
 * </td>
 * </tr>
 * <tr valign="top">
 * <td>passwd</td>
 * <td>
 * The passwd element contains the user's password in an
 * encrypted format. Often, for example on a system employing
 * "shadow" passwords, an asterisk is returned instead.
 * </td>
 * </tr>
 * <tr valign="top">
 * <td>uid</td>
 * <td>
 * User ID of the user in numeric form.
 * </td>
 * </tr>
 * <tr valign="top">
 * <td>gid</td>
 * <td>
 * The group ID of the user. Use the function
 * <b>posix_getgrgid</b> to resolve the group
 * name and a list of its members.
 * </td>
 * </tr>
 * <tr valign="top">
 * <td>gecos</td>
 * <td>
 * GECOS is an obsolete term that refers to the finger
 * information field on a Honeywell batch processing system.
 * The field, however, lives on, and its contents have been
 * formalized by POSIX. The field contains a comma separated
 * list containing the user's full name, office phone, office
 * number, and home phone number. On most systems, only the
 * user's full name is available.
 * </td>
 * </tr>
 * <tr valign="top">
 * <td>dir</td>
 * <td>
 * This element contains the absolute path to the home
 * directory of the user.
 * </td>
 * </tr>
 * <tr valign="top">
 * <td>shell</td>
 * <td>
 * The shell element contains the absolute path to the
 * executable of the user's default shell.
 * </td>
 * </tr>
 * </table>
 * @since 4.0
 * @since 5.0
 */
function posix_getpwnam ($username) {}

/**
 * Return info about a user by user id
 * @link https://php.net/manual/en/function.posix-getpwuid.php
 * @param int $uid <p>
 * The user identifier.
 * </p>
 * @return array an associative array with the following elements:
 * <table>
 * The user information array
 * <tr valign="top">
 * <td>Element</td>
 * <td>Description</td>
 * </tr>
 * <tr valign="top">
 * <td>name</td>
 * <td>
 * The name element contains the username of the user. This is
 * a short, usually less than 16 character "handle" of the
 * user, not the real, full name.
 * </td>
 * </tr>
 * <tr valign="top">
 * <td>passwd</td>
 * <td>
 * The passwd element contains the user's password in an
 * encrypted format. Often, for example on a system employing
 * "shadow" passwords, an asterisk is returned instead.
 * </td>
 * </tr>
 * <tr valign="top">
 * <td>uid</td>
 * <td>
 * User ID, should be the same as the
 * <i>uid</i> parameter used when calling the
 * function, and hence redundant.
 * </td>
 * </tr>
 * <tr valign="top">
 * <td>gid</td>
 * <td>
 * The group ID of the user. Use the function
 * <b>posix_getgrgid</b> to resolve the group
 * name and a list of its members.
 * </td>
 * </tr>
 * <tr valign="top">
 * <td>gecos</td>
 * <td>
 * GECOS is an obsolete term that refers to the finger
 * information field on a Honeywell batch processing system.
 * The field, however, lives on, and its contents have been
 * formalized by POSIX. The field contains a comma separated
 * list containing the user's full name, office phone, office
 * number, and home phone number. On most systems, only the
 * user's full name is available.
 * </td>
 * </tr>
 * <tr valign="top">
 * <td>dir</td>
 * <td>
 * This element contains the absolute path to the
 * home directory of the user.
 * </td>
 * </tr>
 * <tr valign="top">
 * <td>shell</td>
 * <td>
 * The shell element contains the absolute path to the
 * executable of the user's default shell.
 * </td>
 * </tr>
 * </table>
 * @since 4.0
 * @since 5.0
 */
function posix_getpwuid ($uid) {}

/**
 * Return info about system resource limits
 * @link https://php.net/manual/en/function.posix-getrlimit.php
 * @return array an associative array of elements for each
 * limit that is defined. Each limit has a soft and a hard limit.
 * <table>
 * List of possible limits returned
 * <tr valign="top">
 * <td>Limit name</td>
 * <td>Limit description</td>
 * </tr>
 * <tr valign="top">
 * <td>core</td>
 * <td>
 * The maximum size of the core file. When 0, not core files are
 * created. When core files are larger than this size, they will
 * be truncated at this size.
 * </td>
 * </tr>
 * <tr valign="top">
 * <td>totalmem</td>
 * <td>
 * The maximum size of the memory of the process, in bytes.
 * </td>
 * </tr>
 * <tr valign="top">
 * <td>virtualmem</td>
 * <td>
 * The maximum size of the virtual memory for the process, in bytes.
 * </td>
 * </tr>
 * <tr valign="top">
 * <td>data</td>
 * <td>
 * The maximum size of the data segment for the process, in bytes.
 * </td>
 * </tr>
 * <tr valign="top">
 * <td>stack</td>
 * <td>
 * The maximum size of the process stack, in bytes.
 * </td>
 * </tr>
 * <tr valign="top">
 * <td>rss</td>
 * <td>
 * The maximum number of virtual pages resident in RAM
 * </td>
 * </tr>
 * <tr valign="top">
 * <td>maxproc</td>
 * <td>
 * The maximum number of processes that can be created for the
 * real user ID of the calling process.
 * </td>
 * </tr>
 * <tr valign="top">
 * <td>memlock</td>
 * <td>
 * The maximum number of bytes of memory that may be locked into RAM.
 * </td>
 * </tr>
 * <tr valign="top">
 * <td>cpu</td>
 * <td>
 * The amount of time the process is allowed to use the CPU.
 * </td>
 * </tr>
 * <tr valign="top">
 * <td>filesize</td>
 * <td>
 * The maximum size of the data segment for the process, in bytes.
 * </td>
 * </tr>
 * <tr valign="top">
 * <td>openfiles</td>
 * <td>
 * One more than the maximum number of open file descriptors.
 * </td>
 * </tr>
 * </table>
 * @since 4.0
 * @since 5.0
 */
function posix_getrlimit () {}

/**
 * Retrieve the error number set by the last posix function that failed
 * @link https://php.net/manual/en/function.posix-get-last-error.php
 * @return int the errno (error number) set by the last posix function that
 * failed. If no errors exist, 0 is returned.
 * @since 4.2.0
 * @since 5.0
 */
function posix_get_last_error () {}

/**
 * Alias of <b>posix_get_last_error</b>
 * @link https://php.net/manual/en/function.posix-errno.php
 * @since 4.2.0
 * @since 5.0
 */
function posix_errno () {}

/**
 * Retrieve the system error message associated with the given errno
 * @link https://php.net/manual/en/function.posix-strerror.php
 * @param int $errno <p>
 * A POSIX error number, returned by
 * <b>posix_get_last_error</b>. If set to 0, then the
 * string "Success" is returned.
 * </p>
 * @return string the error message, as a string.
 * @since 4.2.0
 * @since 5.0
 */
function posix_strerror ($errno) {}

/**
 * Calculate the group access list
 * @link https://php.net/manual/en/function.posix-initgroups.php
 * @param string $name <p>
 * The user to calculate the list for.
 * </p>
 * @param int $base_group_id <p>
 * Typically the group number from the password file.
 * </p>
 * @return bool <b>TRUE</b> on success or <b>FALSE</b> on failure.
 * @since 5.2.0
 */
function posix_initgroups ($name, $base_group_id) {}


/**
 * Check whether the file exists.
 * @link https://php.net/manual/en/posix.constants.php
 */
define ('POSIX_F_OK', 0);

/**
 * Check whether the file exists and has execute permissions.
 * @link https://php.net/manual/en/posix.constants.php
 */
define ('POSIX_X_OK', 1);

/**
 * Check whether the file exists and has write permissions.
 * @link https://php.net/manual/en/posix.constants.php
 */
define ('POSIX_W_OK', 2);

/**
 * Check whether the file exists and has read permissions.
 * @link https://php.net/manual/en/posix.constants.php
 */
define ('POSIX_R_OK', 4);

/**
 * Normal file
 * @link https://php.net/manual/en/posix.constants.php
 */
define ('POSIX_S_IFREG', 32768);

/**
 * Character special file
 * @link https://php.net/manual/en/posix.constants.php
 */
define ('POSIX_S_IFCHR', 8192);

/**
 * Block special file
 * @link https://php.net/manual/en/posix.constants.php
 */
define ('POSIX_S_IFBLK', 24576);

/**
 * FIFO (named pipe) special file
 * @link https://php.net/manual/en/posix.constants.php
 */
define ('POSIX_S_IFIFO', 4096);

/**
 * Socket
 * @link https://php.net/manual/en/posix.constants.php
 */
define ('POSIX_S_IFSOCK', 49152);

/**
 * The maximum size of the process's address space in bytes. See also PHP's memory_limit configuration directive.
 * @link https://php.net/manual/en/posix.constants.setrlimit.php
 */
define ('POSIX_RLIMIT_AS', 5);
/**
 * The maximum size of a core file. If the limit is set to 0, no core file will be generated.
 * @link https://php.net/manual/en/posix.constants.setrlimit.php
 */
define ('POSIX_RLIMIT_CORE', 4);

/**
 * The maximum amount of CPU time that the process can use, in seconds.
 * When the soft limit is hit, a SIGXCPU signal will be sent, which can be caught with pcntl_signal().
 * Depending on the operating system, additional SIGXCPU signals may be sent each second until the hard limit is hit,
 * at which point an uncatchable SIGKILL signal is sent. See also set_time_limit().
 * @link https://php.net/manual/en/posix.constants.setrlimit.php
 */
define ('POSIX_RLIMIT_CPU', 0);

/**
 * The maximum size of the process's data segment, in bytes.
 * It is extremely unlikely that this will have any effect on
 * the execution of PHP unless an extension is in use that calls brk() or sbrk().
 * @link https://php.net/manual/en/posix.constants.setrlimit.php
 */
define ('POSIX_RLIMIT_DATA', 2);

/**
 * The maximum size of files that the process can create, in bytes.
 * @link https://php.net/manual/en/posix.constants.setrlimit.php
 */
define ('POSIX_RLIMIT_FSIZE', 1);

/**
 * The maximum number of locks that the process can create.
 * This is only supported on extremely old Linux kernels.
 * @link https://php.net/manual/en/posix.constants.setrlimit.php
 */
define('POSIX_RLIMIT_LOCKS', 10);

/**
 * The maximum number of bytes that can be allocated for POSIX message queues.
 * PHP does not ship with support for POSIX message queues,
 * so this limit will not have any effect unless you are using an extension that implements that support.
 * @link https://php.net/manual/en/posix.constants.setrlimit.php
 */
define('POSIX_RLIMIT_MSGQUEUE', 12);

/**
 * The maximum value to which the process can be <a href="https://php.net/manual/en/function.pcntl-setpriority.php"> reniced</a> to. The value that will be used will be 20 - limit, as resource limit values cannot be negative.
 * @link https://php.net/manual/en/posix.constants.setrlimit.php
 */
define('POSIX_RLIMIT_NICE', 13);

/**
 * The maximum real time priority that can be set via the sched_setscheduler() and sched_setparam() system calls.
 * @link https://php.net/manual/en/posix.constants.setrlimit.php
 */
define('POSIX_RLIMIT_RTPRIO', 14);

/**
 * The maximum amount of CPU time, in microseconds,
 * that the process can consume without making a blocking system call if it is using real time scheduling.
 * @link https://php.net/manual/en/posix.constants.setrlimit.php
 */
define('POSIX_RLIMIT_RTTIME', 15);

/**
 * The maximum number of signals that can be queued for the real user ID of the process.
 * @link https://php.net/manual/en/posix.constants.setrlimit.php
 */
define('POSIX_RLIMIT_SIGPENDING', 11);

/**
 * The maximum number of bytes that can be locked into memory.
 * @link https://php.net/manual/en/posix.constants.setrlimit.php
 */
define ('POSIX_RLIMIT_MEMLOCK', 6);

/**
 * A value one greater than the maximum file descriptor number that can be opened by this process.
 * @link https://php.net/manual/en/posix.constants.setrlimit.php
 */
define ('POSIX_RLIMIT_NOFILE', 8);

/**
 * The maximum number of processes (and/or threads, on some operating systems)
 * that can be created for the real user ID of the process.
 * @link https://php.net/manual/en/posix.constants.setrlimit.php
 */
define ('POSIX_RLIMIT_NPROC', 7);

/**
 * The maximum size of the process's resident set, in pages.
 * @link https://php.net/manual/en/posix.constants.setrlimit.php
 */
define ('POSIX_RLIMIT_RSS', 5);

/**
 * The maximum size of the process stack, in bytes.
 * @link https://php.net/manual/en/posix.constants.setrlimit.php
 */
define ('POSIX_RLIMIT_STACK', 3);

/**
 * Used to indicate an infinite value for a resource limit.
 * @link https://php.net/manual/en/posix.constants.setrlimit.php
 */
define ('POSIX_RLIMIT_INFINITY', 9223372036854775807);



// End of posix v.
?>

pcntl函数簇

pcntl_alarm — 为进程设置一个alarm闹钟信号
pcntl_async_signals — Enable/disable asynchronous signal handling or return the old setting
pcntl_errno — 别名 pcntl_get_last_error
pcntl_exec — 在当前进程空间执行指定程序
pcntl_fork — 在当前进程当前位置产生分支(子进程)。译注:fork是创建了一个子进程,父进程和子进程 都从fork的位置开始向下继续执行,不同的是父进程执行过程中,得到的fork返回值为子进程 号,而子进程得到的是0。
pcntl_get_last_error — Retrieve the error number set by the last pcntl function which failed
pcntl_getpriority — 获取任意进程的优先级
pcntl_setpriority — 修改任意进程的优先级
pcntl_signal_dispatch — 调用等待信号的处理器
pcntl_signal_get_handler — Get the current handler for specified signal
pcntl_signal — 安装一个信号处理器
pcntl_sigprocmask — 设置或检索阻塞信号
pcntl_sigtimedwait — 带超时机制的信号等待
pcntl_sigwaitinfo — 等待信号
pcntl_strerror — Retrieve the system error message associated with the given errno
pcntl_wait — 等待或返回fork的子进程状态
pcntl_waitpid — 等待或返回fork的子进程状态
pcntl_wexitstatus — 返回一个中断的子进程的返回代码
pcntl_wifexited — 检查状态代码是否代表一个正常的退出。
pcntl_wifsignaled — 检查子进程状态码是否代表由于某个信号而中断
pcntl_wifstopped — 检查子进程当前是否已经停止
pcntl_wstopsig — 返回导致子进程停止的信号
pcntl_wtermsig — 返回导致子进程中断的信号
<?php

// Start of pcntl v.

/**
 * Forks the currently running process
 * @link https://php.net/manual/en/function.pcntl-fork.php
 * @return int On success, the PID of the child process is returned in the
 * parent's thread of execution, and a 0 is returned in the child's
 * thread of execution. On failure, a -1 will be returned in the
 * parent's context, no child process will be created, and a PHP
 * error is raised.
 * @since 4.1.0
 * @since 5.0
 */
function pcntl_fork () {}

/**
 * Waits on or returns the status of a forked child
 * @link https://php.net/manual/en/function.pcntl-waitpid.php
 * @param int $pid <p>
 * The value of <i>pid</i> can be one of the following:
 * <table>
 * possible values for <i>pid</i>
 * <tr valign="top">
 * <td>&lt; -1</td>
 * <td>
 * wait for any child process whose process group ID is equal to
 * the absolute value of <i>pid</i>.
 * </td>
 * </tr>
 * <tr valign="top">
 * <td>-1</td>
 * <td>
 * wait for any child process; this is the same behaviour that
 * the wait function exhibits.
 * </td>
 * </tr>
 * <tr valign="top">
 * <td>0</td>
 * <td>
 * wait for any child process whose process group ID is equal to
 * that of the calling process.
 * </td>
 * </tr>
 * <tr valign="top">
 * <td>&gt; 0</td>
 * <td>
 * wait for the child whose process ID is equal to the value of
 * <i>pid</i>.
 * </td>
 * </tr>
 * </table>
 * </p>
 * <p>
 * Specifying -1 as the <i>pid</i> is
 * equivalent to the functionality <b>pcntl_wait</b> provides
 * (minus <i>options</i>).
 * </p>
 * @param int $status <p>
 * <b>pcntl_waitpid</b> will store status information
 * in the <i>status</i> parameter which can be
 * evaluated using the following functions:
 * <b>pcntl_wifexited</b>,
 * <b>pcntl_wifstopped</b>,
 * <b>pcntl_wifsignaled</b>,
 * <b>pcntl_wexitstatus</b>,
 * <b>pcntl_wtermsig</b> and
 * <b>pcntl_wstopsig</b>.
 * </p>
 * @param int $options [optional] <p>
 * The value of <i>options</i> is the value of zero
 * or more of the following two global constants
 * OR'ed together:
 * <table>
 * possible values for <i>options</i>
 * <tr valign="top">
 * <td>WNOHANG</td>
 * <td>
 * return immediately if no child has exited.
 * </td>
 * </tr>
 * <tr valign="top">
 * <td>WUNTRACED</td>
 * <td>
 * return for children which are stopped, and whose status has
 * not been reported.
 * </td>
 * </tr>
 * </table>
 * </p>
 * @return int <b>pcntl_waitpid</b> returns the process ID of the
 * child which exited, -1 on error or zero if <b>WNOHANG</b> was used and no
 * child was available
 * @since 4.1.0
 * @since 5.0
 */
function pcntl_waitpid ($pid, &$status, $options = 0) {}

/**
 * Waits on or returns the status of a forked child
 * @link https://php.net/manual/en/function.pcntl-wait.php
 * @param int $status <p>
 * <b>pcntl_wait</b> will store status information
 * in the <i>status</i> parameter which can be
 * evaluated using the following functions:
 * <b>pcntl_wifexited</b>,
 * <b>pcntl_wifstopped</b>,
 * <b>pcntl_wifsignaled</b>,
 * <b>pcntl_wexitstatus</b>,
 * <b>pcntl_wtermsig</b> and
 * <b>pcntl_wstopsig</b>.
 * </p>
 * @param int $options [optional] <p>
 * If wait3 is available on your system (mostly BSD-style systems), you can
 * provide the optional <i>options</i> parameter. If this
 * parameter is not provided, wait will be used for the system call. If
 * wait3 is not available, providing a value for <i>options
 * </i> will have no effect. The value of <i>options
 * </i> is the value of zero or more of the following two constants
 * OR'ed together:
 * <table>
 * Possible values for <i>options</i>
 * <tr valign="top">
 * <td>WNOHANG</td>
 * <td>
 * Return immediately if no child has exited.
 * </td>
 * </tr>
 * <tr valign="top">
 * <td>WUNTRACED</td>
 * <td>
 * Return for children which are stopped, and whose status has
 * not been reported.
 * </td>
 * </tr>
 * </table>
 * </p>
 * @return int <b>pcntl_wait</b> returns the process ID of the
 * child which exited, -1 on error or zero if WNOHANG was provided as an
 * option (on wait3-available systems) and no child was available.
 * @since 5.0
 */
function pcntl_wait (&$status, $options = 0) {}

/**
 * Installs a signal handler
 * @link https://php.net/manual/en/function.pcntl-signal.php
 * @param int $signo <p>
 * The signal number.
 * </p>
 * @param callable|int $handler <p>
 * The signal handler. This may be either a callable, which
 * will be invoked to handle the signal, or either of the two global
 * constants <b>SIG_IGN</b> or <b>SIG_DFL</b>,
 * which will ignore the signal or restore the default signal handler
 * respectively.
 * </p>
 * <p>
 * If a callable is given, it must implement the following
 * signature:
 * </p>
 * <p>
 * void<b>handler</b>
 * <b>int<i>signo</i></b>
 * <i>signo</i>
 * The signal being handled.
 * @param bool $restart_syscalls [optional] <p>
 * Specifies whether system call restarting should be used when this
 * signal arrives.
 * </p>
 * @return bool <b>TRUE</b> on success or <b>FALSE</b> on failure.
 * @since 4.1.0
 * @since 5.0
 */
function pcntl_signal ($signo, $handler, $restart_syscalls = true) {}

/**
 * Calls signal handlers for pending signals
 * @link https://php.net/manual/en/function.pcntl-signal-dispatch.php
 * @return bool <b>TRUE</b> on success or <b>FALSE</b> on failure.
 * @since 5.3.0
 */
function pcntl_signal_dispatch () {}

/**
 * Checks if status code represents a normal exit
 * @link https://php.net/manual/en/function.pcntl-wifexited.php
 * @param int $status The <i>status</i>
 * parameter is the status parameter supplied to a successful
 * call to <b>pcntl_waitpid</b>.</p>
 * @return bool <b>TRUE</b> if the child status code represents a normal exit, <b>FALSE</b>
 * otherwise.
 * @since 4.1.0
 * @since 5.0
 */
function pcntl_wifexited ($status) {}

/**
 * Checks whether the child process is currently stopped
 * @link https://php.net/manual/en/function.pcntl-wifstopped.php
 * @param int $status The <i>status</i>
 * parameter is the status parameter supplied to a successful
 * call to <b>pcntl_waitpid</b>.</p>
 * @return bool <b>TRUE</b> if the child process which caused the return is
 * currently stopped, <b>FALSE</b> otherwise.
 * @since 4.1.0
 * @since 5.0
 */
function pcntl_wifstopped ($status) {}

/**
 * Checks whether the status code represents a termination due to a signal
 * @link https://php.net/manual/en/function.pcntl-wifsignaled.php
 * @param int $status The <i>status</i>
 * parameter is the status parameter supplied to a successful
 * call to <b>pcntl_waitpid</b>.</p>
 * @return bool <b>TRUE</b> if the child process exited because of a signal which was
 * not caught, <b>FALSE</b> otherwise.
 * @since 4.1.0
 * @since 5.0
 */
function pcntl_wifsignaled ($status) {}

/**
 * Returns the return code of a terminated child
 * @link https://php.net/manual/en/function.pcntl-wexitstatus.php
 * @param int $status The <i>status</i>
 * parameter is the status parameter supplied to a successful
 * call to <b>pcntl_waitpid</b>.</p>
 * @return int the return code, as an integer.
 * @since 4.1.0
 * @since 5.0
 */
function pcntl_wexitstatus ($status) {}

/**
 * @param int $status
 */
function pcntl_wifcontinued ( $status){}
/**
 * Returns the signal which caused the child to terminate
 * @link https://php.net/manual/en/function.pcntl-wtermsig.php
 * @param int $status The <i>status</i>
 * parameter is the status parameter supplied to a successful
 * call to <b>pcntl_waitpid</b>.</p>
 * @return int the signal number, as an integer.
 * @since 4.1.0
 * @since 5.0
 */
function pcntl_wtermsig ($status) {}

/**
 * Returns the signal which caused the child to stop
 * @link https://php.net/manual/en/function.pcntl-wstopsig.php
 * @param int $status The <i>status</i>
 * parameter is the status parameter supplied to a successful
 * call to <b>pcntl_waitpid</b>.</p>
 * @return int the signal number.
 * @since 4.1.0
 * @since 5.0
 */
function pcntl_wstopsig ($status) {}

/**
 * Executes specified program in current process space
 * @link https://php.net/manual/en/function.pcntl-exec.php
 * @param string $path <p>
 * <i>path</i> must be the path to a binary executable or a
 * script with a valid path pointing to an executable in the shebang (
 * #!/usr/local/bin/perl for example) as the first line. See your system's
 * man execve(2) page for additional information.
 * </p>
 * @param array $args [optional] <p>
 * <i>args</i> is an array of argument strings passed to the
 * program.
 * </p>
 * @param array $envs [optional] <p>
 * <i>envs</i> is an array of strings which are passed as
 * environment to the program. The array is in the format of name => value,
 * the key being the name of the environmental variable and the value being
 * the value of that variable.
 * </p>
 * @return void <b>FALSE</b> on error and does not return on success.
 * @since 4.2.0
 * @since 5.0
 */
function pcntl_exec ($path, array $args = null, array $envs = null) {}

/**
 * Set an alarm clock for delivery of a signal
 * @link https://php.net/manual/en/function.pcntl-alarm.php
 * @param int $seconds <p>
 * The number of seconds to wait. If <i>seconds</i> is
 * zero, no new alarm is created.
 * </p>
 * @return int the time in seconds that any previously scheduled alarm had
 * remaining before it was to be delivered, or 0 if there
 * was no previously scheduled alarm.
 * @since 4.3.0
 * @since 5.0
 */
function pcntl_alarm ($seconds) {}

/**
 * Retrieve the error number set by the last pcntl function which failed
 * @link https://php.net/manual/en/function.pcntl-get-last-error.php
 * @return int error code.
 * @since 5.3.4
 */
function pcntl_get_last_error () {}

/**
 * Alias of <b>pcntl_strerror</b>
 * @link https://php.net/manual/en/function.pcntl-errno.php
 * @since 5.3.4
 */
function pcntl_errno () {}

/**
 * Retrieve the system error message associated with the given errno
 * @link https://php.net/manual/en/function.pcntl-strerror.php
 * @param int $errno <p>
 * </p>
 * @return string error description on success or <b>FALSE</b> on failure.
 * @since 5.3.4
 */
function pcntl_strerror ($errno) {}

/**
 * Get the priority of any process
 * @link https://php.net/manual/en/function.pcntl-getpriority.php
 * @param int $pid [optional] <p>
 * If not specified, the pid of the current process  (getmypid()) is used.
 * </p>
 * @param int $process_identifier [optional] <p>
 * One of <b>PRIO_PGRP</b>, <b>PRIO_USER</b>
 * or <b>PRIO_PROCESS</b>.
 * </p>
 * @return int <b>pcntl_getpriority</b> returns the priority of the process
 * or <b>FALSE</b> on error. A lower numerical value causes more favorable
 * scheduling.
 * @since 5.0
 */
function pcntl_getpriority ($pid, $process_identifier = PRIO_PROCESS) {}

/**
 * Change the priority of any process
 * @link https://php.net/manual/en/function.pcntl-setpriority.php
 * @param int $priority <p>
 * <i>priority</i> is generally a value in the range
 * -20 to 20. The default priority
 * is 0 while a lower numerical value causes more
 * favorable scheduling. Because priority levels can differ between
 * system types and kernel versions, please see your system's setpriority(2)
 * man page for specific details.
 * </p>
 * @param int $pid [optional] <p>
 * If not specified, the pid of the current process (getmypid()) is used.
 * </p>
 * @param int $process_identifier [optional] <p>
 * One of <b>PRIO_PGRP</b>, <b>PRIO_USER</b>
 * or <b>PRIO_PROCESS</b>.
 * </p>
 * @return bool <b>TRUE</b> on success or <b>FALSE</b> on failure.
 * @since 5.0
 */
function pcntl_setpriority ($priority, $pid, $process_identifier = PRIO_PROCESS) {}

/**
 * Sets and retrieves blocked signals
 * @link https://php.net/manual/en/function.pcntl-sigprocmask.php
 * @param int $how <p>
 * Sets the behavior of <b>pcntl_sigprocmask</b>. Possible
 * values:
 * <b>SIG_BLOCK</b>: Add the signals to the
 * currently blocked signals.
 * <b>SIG_UNBLOCK</b>: Remove the signals from the
 * currently blocked signals.
 * <b>SIG_SETMASK</b>: Replace the currently
 * blocked signals by the given list of signals.
 * </p>
 * @param array $set <p>
 * List of signals.
 * </p>
 * @param array $oldset [optional] <p>
 * The <i>oldset</i> parameter is set to an array
 * containing the list of the previously blocked signals.
 * </p>
 * @return bool <b>TRUE</b> on success or <b>FALSE</b> on failure.
 * @since 5.3.0
 */
function pcntl_sigprocmask ($how, array $set, array &$oldset = null) {}

/**
 * Waits for signals
 * @link https://php.net/manual/en/function.pcntl-sigwaitinfo.php
 * @param array $set <p>
 * Array of signals to wait for.
 * </p>
 * @param array $siginfo [optional] <p>
 * The <i>siginfo</i> parameter is set to an array containing
 * informations about the signal.
 * </p>
 * <p>
 * The following elements are set for all signals:
 * signo: Signal number
 * errno: An error number
 * code: Signal code
 * </p>
 * <p>
 * The following elements may be set for the <b>SIGCHLD</b> signal:
 * status: Exit value or signal
 * utime: User time consumed
 * stime: System time consumed
 * pid: Sending process ID
 * uid: Real user ID of sending process
 * </p>
 * <p>
 * The following elements may be set for the <b>SIGILL</b>,
 * <b>SIGFPE</b>, <b>SIGSEGV</b> and
 * <b>SIGBUS</b> signals:
 * addr: Memory location which caused fault
 * </p>
 * <p>
 * The following element may be set for the <b>SIGPOLL</b>
 * signal:
 * band: Band event
 * fd: File descriptor number
 * </p>
 * @return int On success, <b>pcntl_sigwaitinfo</b> returns a signal number.
 * @since 5.3.0
 */
function pcntl_sigwaitinfo (array $set, array &$siginfo = null) {}

/**
 * Waits for signals, with a timeout
 * @link https://php.net/manual/en/function.pcntl-sigtimedwait.php
 * @param array $set <p>
 * Array of signals to wait for.
 * </p>
 * @param array $siginfo [optional] <p>
 * The <i>siginfo</i> is set to an array containing
 * informations about the signal. See
 * <b>pcntl_sigwaitinfo</b>.
 * </p>
 * @param int $seconds [optional] <p>
 * Timeout in seconds.
 * </p>
 * @param int $nanoseconds [optional] <p>
 * Timeout in nanoseconds.
 * </p>
 * @return int On success, <b>pcntl_sigtimedwait</b> returns a signal number.
 * @since 5.3.0
 */
function pcntl_sigtimedwait (array $set, array &$siginfo = null, $seconds = 0, $nanoseconds = 0) {}

/**
 *
 * @param bool $on
 * @return bool
 * @since 7.1
 */
function pcntl_async_signals($on) {}

/**
 * @param int $signo
 * @return bool
 * @since 7.1
 */
function pcntl_signal_get_handler($signo) {}

define ('WNOHANG', 1);
define ('WUNTRACED', 2);
define ('WCONTINUED', 16);
define ('SIG_IGN', 1);
define ('SIG_DFL', 0);
define ('SIG_ERR', -1);
define ('SIGHUP', 1);
define ('SIGINT', 2);
define ('SIGQUIT', 3);
define ('SIGILL', 4);
define ('SIGTRAP', 5);
define ('SIGABRT', 6);
define ('SIGIOT', 6);
define ('SIGBUS', 7);
define ('SIGFPE', 8);
define ('SIGKILL', 9);
define ('SIGUSR1', 10);
define ('SIGSEGV', 11);
define ('SIGUSR2', 12);
define ('SIGPIPE', 13);
define ('SIGALRM', 14);
define ('SIGTERM', 15);
define ('SIGSTKFLT', 16);
define ('SIGCLD', 17);
define ('SIGCHLD', 17);
define ('SIGCONT', 18);
define ('SIGSTOP', 19);
define ('SIGTSTP', 20);
define ('SIGTTIN', 21);
define ('SIGTTOU', 22);
define ('SIGURG', 23);
define ('SIGXCPU', 24);
define ('SIGXFSZ', 25);
define ('SIGVTALRM', 26);
define ('SIGPROF', 27);
define ('SIGWINCH', 28);
define ('SIGPOLL', 29);
define ('SIGIO', 29);
define ('SIGPWR', 30);
define ('SIGSYS', 31);
define ('SIGBABY', 31);
define ('PRIO_PGRP', 1);
define ('PRIO_USER', 2);
define ('PRIO_PROCESS', 0);

/**
 * @link https://php.net/manual/en/pcntl.constants.php
 * @since 5.3.0
 */
define ('SIG_BLOCK', 0);

/**
 * @link https://php.net/manual/en/pcntl.constants.php
 * @since 5.3.0
 */
define ('SIG_UNBLOCK', 1);

/**
 * @link https://php.net/manual/en/pcntl.constants.php
 * @since 5.3.0
 */
define ('SIG_SETMASK', 2);

/**
 * @link https://php.net/manual/en/pcntl.constants.php
 * @since 5.3.0
 */
define ('SI_USER', 0);

/**
 * @link https://php.net/manual/en/pcntl.constants.php
 * @since 5.3.0
 */
define ('SI_KERNEL', 128);

/**
 * @link https://php.net/manual/en/pcntl.constants.php
 * @since 5.3.0
 */
define ('SI_QUEUE', -1);

/**
 * @link https://php.net/manual/en/pcntl.constants.php
 * @since 5.3.0
 */
define ('SI_TIMER', -2);
define ('SI_MESGQ', -3);

/**
 * @link https://php.net/manual/en/pcntl.constants.php
 * @since 5.3.0
 */
define ('SI_ASYNCIO', -4);

/**
 * @link https://php.net/manual/en/pcntl.constants.php
 * @since 5.3.0
 */
define ('SI_SIGIO', -5);

/**
 * @link https://php.net/manual/en/pcntl.constants.php
 * @since 5.3.0
 */
define ('SI_TKILL', -6);

/**
 * @link https://php.net/manual/en/pcntl.constants.php
 * @since 5.3.0
 */
define ('CLD_EXITED', 1);

/**
 * @link https://php.net/manual/en/pcntl.constants.php
 * @since 5.3.0
 */
define ('CLD_KILLED', 2);

/**
 * @link https://php.net/manual/en/pcntl.constants.php
 * @since 5.3.0
 */
define ('CLD_DUMPED', 3);

/**
 * @link https://php.net/manual/en/pcntl.constants.php
 * @since 5.3.0
 */
define ('CLD_TRAPPED', 4);

/**
 * @link https://php.net/manual/en/pcntl.constants.php
 * @since 5.3.0
 */
define ('CLD_STOPPED', 5);

/**
 * @link https://php.net/manual/en/pcntl.constants.php
 * @since 5.3.0
 */
define ('CLD_CONTINUED', 6);

/**
 * @link https://php.net/manual/en/pcntl.constants.php
 * @since 5.3.0
 */
define ('TRAP_BRKPT', 1);

/**
 * @link https://php.net/manual/en/pcntl.constants.php
 * @since 5.3.0
 */
define ('TRAP_TRACE', 2);

/**
 * @link https://php.net/manual/en/pcntl.constants.php
 * @since 5.3.0
 */
define ('POLL_IN', 1);

/**
 * @link https://php.net/manual/en/pcntl.constants.php
 * @since 5.3.0
 */
define ('POLL_OUT', 2);

/**
 * @link https://php.net/manual/en/pcntl.constants.php
 * @since 5.3.0
 */
define ('POLL_MSG', 3);

/**
 * @link https://php.net/manual/en/pcntl.constants.php
 * @since 5.3.0
 */
define ('POLL_ERR', 4);

/**
 * @link https://php.net/manual/en/pcntl.constants.php
 * @since 5.3.0
 */
define ('POLL_PRI', 5);

/**
 * @link https://php.net/manual/en/pcntl.constants.php
 * @since 5.3.0
 */
define ('POLL_HUP', 6);

/**
 * @link https://php.net/manual/en/pcntl.constants.php
 * @since 5.3.0
 */
define ('ILL_ILLOPC', 1);

/**
 * @link https://php.net/manual/en/pcntl.constants.php
 * @since 5.3.0
 */
define ('ILL_ILLOPN', 2);

/**
 * @link https://php.net/manual/en/pcntl.constants.php
 * @since 5.3.0
 */
define ('ILL_ILLADR', 3);

/**
 * @link https://php.net/manual/en/pcntl.constants.php
 * @since 5.3.0
 */
define ('ILL_ILLTRP', 4);

/**
 * @link https://php.net/manual/en/pcntl.constants.php
 * @since 5.3.0
 */
define ('ILL_PRVOPC', 5);

/**
 * @link https://php.net/manual/en/pcntl.constants.php
 * @since 5.3.0
 */
define ('ILL_PRVREG', 6);

/**
 * @link https://php.net/manual/en/pcntl.constants.php
 * @since 5.3.0
 */
define ('ILL_COPROC', 7);

/**
 * @link https://php.net/manual/en/pcntl.constants.php
 * @since 5.3.0
 */
define ('ILL_BADSTK', 8);

/**
 * @link https://php.net/manual/en/pcntl.constants.php
 * @since 5.3.0
 */
define ('FPE_INTDIV', 1);

/**
 * @link https://php.net/manual/en/pcntl.constants.php
 * @since 5.3.0
 */
define ('FPE_INTOVF', 2);

/**
 * @link https://php.net/manual/en/pcntl.constants.php
 * @since 5.3.0
 */
define ('FPE_FLTDIV', 3);

/**
 * @link https://php.net/manual/en/pcntl.constants.php
 * @since 5.3.0
 */
define ('FPE_FLTOVF', 4);

/**
 * @link https://php.net/manual/en/pcntl.constants.php
 * @since 5.3.0
 */
define ('FPE_FLTUND', 7);

/**
 * @link https://php.net/manual/en/pcntl.constants.php
 * @since 5.3.0
 */
define ('FPE_FLTRES', 6);

/**
 * @link https://php.net/manual/en/pcntl.constants.php
 * @since 5.3.0
 */
define ('FPE_FLTINV', 7);

/**
 * @link https://php.net/manual/en/pcntl.constants.php
 * @since 5.3.0
 */
define ('FPE_FLTSUB', 8);

/**
 * @link https://php.net/manual/en/pcntl.constants.php
 * @since 5.3.0
 */
define ('SEGV_MAPERR', 1);

/**
 * @link https://php.net/manual/en/pcntl.constants.php
 * @since 5.3.0
 */
define ('SEGV_ACCERR', 2);

/**
 * @link https://php.net/manual/en/pcntl.constants.php
 * @since 5.3.0
 */
define ('BUS_ADRALN', 1);

/**
 * @link https://php.net/manual/en/pcntl.constants.php
 * @since 5.3.0
 */
define ('BUS_ADRERR', 2);

/**
 * @link https://php.net/manual/en/pcntl.constants.php
 * @since 5.3.0
 */
define ('BUS_OBJERR', 3);
define ('PCNTL_EINTR', 4);
define ('PCNTL_ECHILD', 10);
define ('PCNTL_EINVAL', 22);
define ('PCNTL_EAGAIN', 11);
define ('PCNTL_ESRCH', 3);
define ('PCNTL_EACCES', 13);
define ('PCNTL_EPERM', 1);
define ('PCNTL_ENOMEM', 12);
define ('PCNTL_E2BIG', 7);
define ('PCNTL_EFAULT', 14);
define ('PCNTL_EIO', 5);
define ('PCNTL_EISDIR', 21);
define ('PCNTL_ELIBBAD', 80);
define ('PCNTL_ELOOP', 40);
define ('PCNTL_EMFILE', 24);
define ('PCNTL_ENAMETOOLONG', 36);
define ('PCNTL_ENFILE', 23);
define ('PCNTL_ENOENT', 2);
define ('PCNTL_ENOEXEC', 8);
define ('PCNTL_ENOTDIR', 20);
define ('PCNTL_ETXTBSY', 26);

// End of pcntl v.
?>






参考资料

PHP进程及进程间通信 https://www.cnblogs.com/aksir/p/6777671.html

Qt 中的多线程技术 https://zhuanlan.zhihu.com/p/52612180

PHP 手册 函数参考 进程控制扩展 进程控制 https://www.php.net/manual/zh/book.pcntl.php

PHP 手册 函数参考 进程控制扩展 POSIX https://www.php.net/manual/zh/book.posix.php

PHP 手册 函数参考 进程控制扩展 pthreads https://www.php.net/manual/zh/book.pthreads.php

PHP 线程,进程和并发 https://blog.csdn.net/qq_36514588/article/details/81868323

记录PHP的进程和线程理解 https://www.cnblogs.com/fuwentao/p/9241420.html

线程和进程的区别是什么? https://www.zhihu.com/question/25532384?sort=created

多线程编程 - PHP 实现 https://www.cnblogs.com/zhenbianshu/p/7978835.html

linux环境下多线程编程 https://zhuanlan.zhihu.com/p/73317603

认识系统服务 (daemons) https://www.cnblogs.com/cshaptx4869/p/11115334.html

深入研究PHP及Zend Engine的线程安全模型 http://blog.codinglabs.org/articles/zend-thread-safety.html

“守护进程”(daemon)就是一直在后台运行的进程 https://www.cnblogs.com/boodoog/p/6043083.html

【Linux编程】守护进程(daemon)详解与创建 https://blog.csdn.net/a511244213/article/details/79625801


返回