Skip to content

Commit d4dd3df

Browse files
committed
Process v1.0
0 parents  commit d4dd3df

File tree

7 files changed

+479
-0
lines changed

7 files changed

+479
-0
lines changed

.gitattributes

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
* text=auto
2+
3+
/examples export-ignore
4+
/.* export-ignore

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
!.gitkeep
2+
vendor
3+
composer.lock

README.md

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
Soli Process
2+
------------
3+
4+
基于 pcntl 和 posix 扩展,简单的 PHP 多进程管理类库。
5+
6+
## 依赖
7+
8+
- Unix-like
9+
- PHP 5.0+
10+
- ext-pcntl
11+
- ext-posix
12+
13+
`注:信号处理部分需要 PHP 7.1+`
14+
15+
16+
## 安装
17+
18+
使用 `composer` 进行安装:
19+
20+
composer require soliphp/process
21+
22+
23+
## 快速使用
24+
25+
<?php
26+
27+
use Soli\Process;
28+
29+
include __DIR__ . "/vendor/autoload.php";
30+
31+
$job = function ($worker) {
32+
while (1) {
33+
echo "Hello world, master pid: {$worker->masterPid}, worker pid: {$worker->workerPid}, worker id: {$worker->id}\n";
34+
sleep(1);
35+
}
36+
};
37+
38+
$proc = new Process();
39+
$proc->name = 'soli process test';
40+
$proc->count = 2;
41+
$proc->daemonize = 0;
42+
$proc->logFile = '/tmp/soli_process.log';
43+
44+
$proc->setJob($job);
45+
46+
$proc->start();
47+
48+
49+
## 进程结构
50+
51+
`Soli\Process` 使用 Master-Worker 进程模型:
52+
53+
[ master ]
54+
/ | \
55+
/ v \
56+
[Worker1] [Worker2] [WorkerN]
57+
58+
master 进程 fork worker 进程,在 PHP 7.1+ 下 master 进程还会接收终止信号传递给 worker 进程执行退出。
59+
60+
61+
## 函数列表
62+
63+
### setJob
64+
65+
设置 worker 进程需要执行的任务。
66+
67+
Process->setJob(callable $job)
68+
69+
关于 callable 类型参见[官方文档]
70+
71+
如这里使用匿名函数定义 job,输出一条信息退出进程:
72+
73+
$proc = new Process();
74+
75+
$proc->setJob(function ($worker) {
76+
echo "Hello world, master pid: {$worker->masterPid}, worker pid: {$worker->workerPid}, worker id: {$worker->id}\n";
77+
});
78+
79+
`在 job 回调参数中会返回当前 worker 进程的 $worker 实例`,通过这个 $worker 实例可以获取以下[属性列表]中的中的属性。
80+
81+
### start
82+
83+
启动进程,将根据设置的 `count` 启动相应个 worker 进程。
84+
85+
Process->start()
86+
87+
88+
## 属性列表
89+
90+
### id
91+
92+
当前 worker 进程的编号,编号范围:[1, $worker->count]
93+
94+
`可在 job 回调中使用`
95+
96+
### masterPid
97+
98+
当前 master 进程 PID。
99+
100+
`可在 job 回调中使用`
101+
102+
### workerPid
103+
104+
当前 worker 进程 PID。
105+
106+
`可在 job 回调中使用`
107+
108+
### name
109+
110+
当前 master/worker 进程的名称,只支持 Linux。
111+
112+
执行设置进程名称时:
113+
114+
master 进程会自动在其后追加 master 文本,最终的进程名称为 `$name master`
115+
116+
worker 进程会自动在其后追加 worker 文本,最终的进程名称为 `$name worker`
117+
118+
### count
119+
120+
设置启动的 worker 进程数,默认为 1
121+
122+
### daemonize
123+
124+
是否将程序作为守护进程运行。
125+
126+
启用守护进程后,标准输出和错误会被重定向到 `logFile`
127+
128+
如果未设置 `logFile`,将重定向到 `/dev/null`,所有打印到屏幕的信息都会被丢弃。
129+
130+
### logFile
131+
132+
运行期发生的异常信息、进程的终止信息等会记录到这个文件;
133+
134+
启用守护进程后,所有打印到屏幕的信息也都会写入到这个文件。
135+
136+
137+
## 信号处理
138+
139+
信号处理部分使用了 [pcntl_async_signals] 需要 `PHP 7.1+` 支持。
140+
141+
master 进程支持接收 `SIGINT`, `SIGTERM` 终止信号,master 进程接收到终止信号后向所有 worker
142+
进程发送相应的终止信号,worker 进程接收到终止信号后执行退出操作。
143+
144+
我们可以通过 `kill` 命令发送信号:
145+
146+
kill -SIGINT <master pid>
147+
kill -SIGTERM <master pid>
148+
149+
也可以直接通过信号所对应的数字参数:
150+
151+
kill -2 <master pid>
152+
kill -15 <master pid>
153+
154+
`SIGINT` 即为在终端按下的 `CTRL + C`
155+
156+
注:如果使用 `kill -9``kill -SIGKILL` 对 master
157+
进程发送终止信号,master 进程会立即终止,并不会再向 worker
158+
进程发送终止信号,所以如果是要通过 master 进程终止所有 worker 进程,建议使用
159+
`kill -15` 终止所有 worker 进程。
160+
161+
162+
低于 PHP 7.1 可以使用以下命令终止所有 worker 进程,注意替换为你的 "process name":
163+
164+
ps aux | grep "process name" | grep -v grep | awk '{ print $2 }' | xargs kill -9
165+
166+
167+
## License
168+
169+
MIT Public License
170+
171+
172+
[pcntl_async_signals]: http://php.net/pcntl_async_signals
173+
[官方文档]: http://php.net/callable
174+
[属性列表]: #属性列表

composer.json

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
{
2+
"name": "soliphp/process",
3+
"description": "Simple multi-process manager for PHP, based on pcntl and posix.",
4+
"type": "library",
5+
"keywords": ["multi-process", "process", "soliphp", "soli"],
6+
"homepage": "https://github.com/soliphp/process",
7+
"support": {
8+
"issues": "https://github.com/soliphp/process/issues",
9+
"source": "https://github.com/soliphp/process"
10+
},
11+
"license": "MIT",
12+
"authors": [
13+
{
14+
"name": "ueaner",
15+
"email": "[email protected]"
16+
}
17+
],
18+
"require": {
19+
"php": ">=5.0",
20+
"ext-pcntl": "*",
21+
"ext-posix": "*"
22+
},
23+
"suggest": {
24+
"signals": "Signal handling needs PHP 7.1+."
25+
},
26+
"autoload": {
27+
"psr-4": {
28+
"Soli\\": "src/"
29+
},
30+
"files": [
31+
"src/helpers.php"
32+
]
33+
},
34+
"minimum-stability": "dev"
35+
}

examples/01.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
use Soli\Process;
4+
5+
include __DIR__ . "/../vendor/autoload.php";
6+
7+
$job = function ($worker) {
8+
while (1) {
9+
echo "Hello world, master pid: {$worker->masterPid}, worker pid: {$worker->workerPid}, worker id: {$worker->id}\n";
10+
sleep(1);
11+
}
12+
};
13+
14+
$proc = new Process();
15+
$proc->name = 'soli process 01';
16+
$proc->count = 2;
17+
$proc->daemonize = 0;
18+
// 启用守护进程后,所有打印到屏幕的信息将会写入到 logFile 文件
19+
$proc->logFile = '/tmp/soli_process.log';
20+
21+
$proc->setJob($job);
22+
23+
$proc->start();

0 commit comments

Comments
 (0)