如何理解workerman中主进程与子进程?
一般来说在Worker::runAll();
调用前运行的代码都是在主进程运行的,onXXX
回调运行的代码都属于子进程。注意写在Worker::runAll();
后面的代码永远不会被执行。
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
require_once __DIR__ . '/vendor/autoload.php';
// 运行在主进程
$tcp_worker = new Worker("tcp://0.0.0.0:2347");
// 赋值过程运行在主进程
$tcp_worker->onMessage = function(TcpConnection $connection, $data)
{
// 这部分运行在子进程
$connection->send('hello ' . $data);
};
Worker::runAll();
注意代码中的注释哦!
注意:
1、不要在主进程中初始化数据库、memcache
、redis
等连接资源,因为主进程初始化的连接可能会被子进程自动继承(尤其是使用单例的时候),所有进程都持有同一个连接,服务端通过这个连接返回的数据在多个进程上都可读,会导致数据错乱。同样的,如果任何一个进程关闭连接(例如daemon
模式运行时主进程会退出导致连接关闭),都导致所有子进程的连接都被一起关闭,并发生不可预知的错误,例如mysql gone away
错误。
2、推荐在onWorkerStart
里面初始化连接资源。