php默认是单进程运行, 这几天php写了一个数据处理脚本, 发现很吃力, 50w的数据, 跑了1个半小时, 好累!
于是想到了swoole的swoole_process来实现提提速度。也发现了一些问题, 记录下。
- swoole创建的进程一定要调用
swoole_process::wait()
来等待回收, 不然就成为了僵死进程了。
swoole_process(callback, false, false)
中的callback
中的**$this
**就是完全fork出来的父对象, 里面
的变量, 在子进程的独立空间中, 不能数据共享. 如果要父子进程数据共享, 可以使用swoole_table
创建全局共享 内存实现数据共享。
- 使用多进程操作数据库的时候, 注意, 不能多进程更新数据库中的同一行数据, 否则(innodb)出现死锁, (myisam) 数据会出现混乱。
下面是事例代码
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
| class MultipleProcessDemo {
public $pidList = [];
const MAX_PROCESS_NUM = 10;
public $mpid = 0;
public function run() { $this->processStart(); for($i = 0; $i < self::MAX_PROCESS_NUM; $i++) { $this->subprocess(); } $this->processWait(); }
protected function processStart() { swoole_set_process_name(sprintf('hello-multiple-process:%s', 'master')); $this->mpid = posix_getpid(); }
public function subprocess() { $mpid = $this->mpid; $subprocess = new \swoole_process(function($work) use ($mpid) { $subpid = uniqid(); swoole_set_process_name(sprintf('hello-multiple-process:%s', $subpid)); if(!swoole_process::kill($mpid, 0)){ $work->exit(); } echo sprintf("subprocess is run and pid is 【%s】", $subpid); echo PHP_EOL; sleep(10); }, false, false) $pid = $subprocess->start(); $this->pidList[$pid] = $pid; }
public function processWait() { while(true) { if(count($this->pidList)) { $endprocess = \swoole_process::wait(); if($endprocess === false) { break; } if(isset($endprocess['pid'])) { ecoh sprintf("process 【%s】 end ok", $endprocess['pid']); echo PHP_EOL; unset($this->pidList[$endprocess['pid']]); } } else { break; } } }
}
$multipleTask = new MultipleProcessDemo(); $multipleTask->run();
|
有了多进程编程也不会很难了, PHP5.5.x在处理swoole可能会有BUG:libgc xxxx php free() xxx, 若出现次bug 升级php吧, 不好改!