<?php
class fork {
private $_pid = 0;
public function fork_child() {
$this->_pid = posix_getpid();
cli_set_process_title("LEARN FORK master process ". $this->_pid); //设置进程标识
$childs = array(); //存放子进程ID
foreach(array(10,20,30) as $v) { //模拟多任务
$child = $this->_fork($v); //创建子进程,并保存返回的子进程ID
$childs[$child] = date("H:i:s", time());
}
$pid = pcntl_wait($status); //等待子进程,当前是假设有一个退出则全停的场景
if (isset($childs[$pid])) {
unset($childs[$pid]); //踢出执行完的子进程
foreach($childs as $child=>$date){
posix_kill($child, SIGTERM); //杀死兄弟进程
}
throw new Exception("子进程:".$pid. "异常");
}
}
protected function _fork($sleep) {
$pid = pcntl_fork();
if (0 > $pid) {
echo "fork failed";
} elseif ($pid > 0) {
return $pid; //返回成功创建的子进程ID,父子进程拿到的PID是不一样的
} else {
// if (posix_getppid() != $this->_pid)
// throw new Exception("父进程异常");
cli_set_process_title("LEARN FORK child process ". posix_getpid(). " sleep ". $sleep);
sleep($sleep);
exit;
}
}
}
$fork = new fork();
$fork->fork_child();
如果是进程间通信的可以考虑使用posix_mkfifo函数,用文件,socket~
相关辅助函数
sys_get_temp_dir
cli_set_process_title
call_user_func_array
php_sapi_name
posix_setsid
posix_getpid
posix_getppid
posix_getpwnam
pcntl_fork
pcntl_signal
pcntl_wait
pcntl_wifexited
pcntl_wexitstatus
declare(ticks = 100)
pcntl_signal_dispatch
getlastmod
getmygid
getmyinode
getmypid
getmyuid
getopt
extension_loaded
signal
SIGTERM//中断进程
SIGHUP
SIGQUIT
var cluster = require('cluster'); //引入cluster模块, node是单进程单线程,要并行得借助第三方模块
var numCPUs = require('os').cpus().length; //获取CPU核数,做为进程数
if (cluster.isMaster) {
console.log('[master] ' + "start master...");
var workMap = [];
function forkWorker(env) {
var worker = cluster.fork(env); //可以环境变量{"PORT":XXX}
workMap[worker.id] = env; //保存fork的进程及环境变量
}
for (var i = 0; i < numCPUs; i++) {
forkWorker({"PROCESS":i}); //调用fork功能
}
cluster.on('exit', function(worker, code, signal) {
var env = workMap[worker.id]; //取回退出的进程环境变量
delete workMap[worker.id]; //删除已经退出的进程数据
if (worker.suicide === true) {
forkWorker(env); //正常退出拉起
}else {
forkWorker(env); //异常退出拉起
}
})
} else if (cluster.isWorker) {
console.log('[worker] ' + "start worker ..." + cluster.worker.id + " env-process"+ cluster.worker.process.env.PROCESS);
}