我有一个server.php文件
我在主进程中使用GlobalData变量共享组件。每0.5秒随机赋予$global_client->param一个数字,这一切都是正常。
use Workerman\Lib\Timer;
use Workerman\Worker;
$global_server = new GlobalData\Server('127.0.0.1','13145');
$global_client = new GlobalData\Client('127.0.0.1:13145');
$worker = new Worker();
$worker->onWorkerStart = function() use($global_client) {
//每0.5秒随机设置一个数
Timer::add(0.5, function() use ($global_client){
$global_client->param=rand(1,999999);
});
};
Worker::runAll();
我有一个client.php文件
如果不要while循坏,我再cli模式下能正常获取数据,但是加了while循环几次后就会出现Alarm Clock,我不知道是什么原因。 哪个朋友能给我说明一下原理吗?
用for循环10次也会报这样的错误
$global_client = new GlobalData\Client('127.0.0.1:13145');
while (1){
sleep(1);
print_r($global_client->param);
}
如果用Timer方式循环可以解决问题, 就是我想知道原理是什么?为什么会这样?
我的理解GlobalData变量共享组件 好比数据库,我while就是不停的连接数据库,但是没成功~不知道原理
workerman 不允许这种写法,文档中有说明: http://doc.workerman.net/329713
文档中写的不要有死循环,那么我不用while true 我就for 10次 也一样出现这样的问题
不能用sleep
没记错的话,Client应该在OnXxxxx方法里实例化
文档里:"如果在Workerman环境中使用GlobalData/Client,请在onXXX回调中实例化GlobalData/Client对象,例如在onWorkerStart中实例化。"
@8001:明白了,就是不知道原理。
背后原因:
https://github.com/walkor/GlobalData/blob/master/src/Client.php#L74
https://github.com/walkor/Workerman/blob/master/Timer.php#L127
追踪源码上述源码可以发现定时器触发了pcntl_alarm(1)行为,即1秒后触发了时钟信号,默认会终止当前进程。
解决方案:
目前尚不清楚Timer这里的pcntl_alarm(1)的影响,不过按照你这while写法【目测你这是非workerman环境用法】,原理理解了、客户端可以暂时通过屏蔽时钟信号这样去解决:pcntl_alarm(0); 此外楼上提及的注意事项也要关注。
谢谢你的回复,对我帮助非常大