我在之前的博客中提到,当进程过多时,多进程插入mysql数据库表,超过mysql连接的最大数量。会报错,插入失败。我想通过进程间通信来控制连接数。参考了一些网上的博客,实现了。我使用共享内存来存储mysql连接数。当进程获取到信号量后,在尝试连接数据库之前,先进行判断,当前连接数是否超过预定阈值,如果没有,则连接数据库,连接成功后,连接数加一,立即释放信号。数据库操作完成后,再次阻塞进程获取信号,然后将连接号减一,信号量释放后,进程退出。这样就可以控制mysql的连接数不会达到上限,程序也不会连接不上数据库。当然我也可以直接fork一些进程,只是觉得需要折腾一下。否则,进程通信会混乱。并且不会出现以下问题。但是我自己的实验,fork10000个子进程,虚拟机很容易挂掉。后来是时候fork5000个子进程,插入100万条数据,模拟最原始的插入。虚拟机虽然没有崩溃,但是很卡,期间会出现很多僵尸进程,有点疑惑。多进程耗内存严重,下一步要尝试多线程。ps:为了支持Semaphore功能,php在编译安装时必须加入如下参数:--enable-sysvsem--enable-sysvshm--enable-sysvmsg为此,我也重新编译了php。...好痛。代码如下:0){//$id=pcntl_wait($status,WNOHANG);$孩子[]=$pid;}elseif($pid==0){while(true){//获取信号量sem_acquire($signal);$count=shm_get_var($shm_id,SHARE_KEY);如果($count>=$poolSize){sem_release($signal);继续;}否则{$链接=mysqli_connect('localhost','root','root','yii2advanced');如果($链接){$count++;shm_put_var($shm_id,SHARE_KEY,$count);sem_release($signal);$开始=($i-1)*$per+1;$end=$start+$per;for($j=$start;$j<$end;$j++){$time=microtime(true);$sql='插入pcntl_test(rank,time)值('.$j.','.$time.')';mysqli_query($link,$sql);}mysqli_close($链接);休息;}}睡眠(1);}sem_acquire($信号);$count=shm_get_var($shm_id,SHARE_KEY);$计数--;shm_put_var($shm_id,SHARE_KEY,$count);sem_release($signal);$id=getmypid();$计数++;echo'count:'.$count.'孩子'。$id.'完成'.microtime(true).PHP_EOL;退出(0);}}while(count($child)){foreach($childas$k=>$pid){$res=pcntl_waitpid($pid,$status,WNOHANG);如果(-1==$res||$res>0){未设置($child[$k]);}}}$end=microtime(true);echo'end'.$end.PHP_EOL;echo'fork'.$num.'processinsert'.$total.'重新编码采用'.($end-$begin).PHP_EOL;最后统计分析了5000个进程,100万条记录,插入时,mysql连接数(平均连接数464),用python绘制如下:
