今天进行文件迁移,主进程负责查数据库,并创建多个子任务,而子任务以进程的方式异步执行,如图所示:
但是,随后发现程序开始后不就,主进程在查询数据库时,报MySQL server has gone away 错误;
查了下资料,发现在创建子进程时,父子进程共享同一个socket资源,虽然进程表中有两份socket描述符,但实际上在内核里映射的是同一个socket资源链接,如图:
再看下上图中的程序,当任务进程结束时,把数据库连接也干掉了,这就使得父进程再次查询数据库时,报连接断开的错误MySQL server has gone away ;
解决方案:
(1)每次查表时,都建立新的数据库连接;(缺点:浪费资源)
(2)任务进程在创建数据库连接前创建,以进程池的形式存在,当生成任务时,以进程间通讯方式(共享内存,socket等),让任务进程执行任务;
php-cli方面需要注意的地方:
即使在多进程中每个子进程都使用mysql_connect来生成新的mysql实例,但是mysql_connect函数的第四个参数new_link默认为false,也就是这个扩展在不同进程中进行相同数据库连接时,会复用连接,这也会导致上述问题;