感觉在runAll()之前实例化mysql或者redis是可以的,因为是copy on write

zhuxiaoyu

workerman文档里面建议将redis或者mysql的实例步骤放到onWorkerStart里面,fork之后执行onWorkerStart,这样实例就是属于这个子进程的。
但是在测试中,我发现如果在runAll前实例化,这个资源数据是copy on write的,并没有发现在runAll外面实例化有什么影响
测试代码如下:

[attach]1362[/attach]
 
在id为0的子进程中改变redis实例,并不会影响id为1的子进程
两次curl请求,第二个请求redis插入不进去
 
为了测试copy on write

[attach]1363[/attach]
两次curl请求,第一个输出5,第二个输出10
 
可见:
1.子进程继承父进程的数据,是以copy on write模型
2.在runAll实例化redis和mysql,好像并没有什么不可
 
 
以上不知道是对是错

2479 2 0
2个回答

walkor

高并发下会有问题

  • zhuxiaoyu 2018-11-08

    所以子进程继承父进程的数据,是以copy on write的模式,一开始相当于是同一个数据,在子进程或者父进程改变了数据,之后才会变成两份不一样的数据,这样理解对吧?

  • zhuxiaoyu 2018-11-08

    7.1以上的xdebug_debug_zval不太好用了,没法更直观的展现出copy on write

walkor

比如主进程初始化了一个mysql连接,fork后的各个子进程会继承主进程的连接资源,这个资源猜测应该不会copy on write,你会发现mysql服务端只看到一个连接,但是各个子进程都有能对这个mysql连接读写,如果出现同时读写应该会造成mysql连接异常。

  • 暂无评论
年代过于久远,无法发表回答
🔝