php与pcntl

php与pcntl①

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
<?php
$childs = [];


function daemon()
{
$pid = pcntl_fork();
if ($pid < 0) {
exit('错误无法创建');
}
//子进程执行
if ($pid == 0) {
echo sprintf('deamon子进程逻辑开始执行') . PHP_EOL;
//2.让子进程会话变成主会话
$sid=posix_setsid();
if($sid<=0){
echo('set fail');
}
//3.修改工作目录
if(chdir('/')===false){
echo('fail to change dir ');
}
//4.与chmod相反 默认继承了父进程的文件创建掩码
umask(0);
echo '子进程已经成为deamon'.PHP_EOL;
//5.默认继承了父进程打开的文件,关闭后面子进程的输出输入linux终端
fclose(STDIN);
fclose(STDOUT);
fclose(STDERR);
}
//父进程执行
if ($pid > 0) {
// 第一步
exit('父进程('.posix_getpid().')退出'.PHP_EOL);
}
}


function fork()
{
$pid = pcntl_fork();
if ($pid < 0) exit('错误无法创建');
//子进程执行
if ($pid == 0) {
echo sprintf('子进程(%s)被创建', posix_getpid()) . PHP_EOL;
//子进程永远阻塞这里,可以是业务代码
while (true) {
sleep(10);
}
}
//父进程执行,保留子进程的pid
if ($pid > 0) {
global $childs;
$childs[$pid] = $pid;
}
}

//上面代码,定义 funciont damon() ; function fork()
//父进程退出,子进程接管
daemon();

for ($i=0;$i<3;$i++){
fork();
}

echo '子进程为(' . posix_getpid() . ')已经升级为父进程' . PHP_EOL;
echo '开始作为deamon守护';
while (count($childs)) {
$exit_id = pcntl_wait($status);
if ($exit_id >= 0) {
$msg = pcntl_wtermsig($status);
//删除数组资源句柄
echo sprintf('子进程:(%s) 退出,原因:%s', $exit_id, $msg) . PHP_EOL;
unset($childs[$exit_id]);
}
//monitor 监控子进程
//子进程数量不足2个,就fork()创建子进程
if (count($childs) < 2) {
fork();
}
}

php-pcntl.png

作者

舰长胡椒

发布于

2022-08-19

更新于

2023-10-13

许可协议

评论