当进程数过多时,多进程插入mysql数据库表,超过了mysql最大连接数,就会报错,插入就会有失败的情况。想通过进程间通信来控制一下连接数,
实现了一下,利用共享内存来存放mysql的连接数,当某个进程在获取信号量后,尝试去连接数据库之前查看mysql连接数,先判断一下,当前的连接数是否超过了预定的阈值,如果没有,就连接数据库,连接成功后,连接数加一,立马释放信号,等操作数据库完毕后,进程再次阻塞,来获取信号,然后把连接数减一,释放信号量后,进程退出。
这样就可以控制有mysql的连接数不会达到上限查看mysql连接数,程序不会出现连接数据库失败的情况。当然我可以直接少fork一些进程,本人就是觉得要折腾一下。不然进程通信就懵逼了。而且也不会有以下的问题出现。
但是本人实验,fork一万个子进程,虚拟机很容易就挂了。后来该为fork 5000个子进程,插入一百万条数据,模拟的是最原始的插入。虚拟机虽然没有崩, 但是很卡,期间会出现很多僵尸进程,这里有点疑问。
多进程耗内存比较严重,下一步打算用多线程来试试。
ps:要支持Semaphore函数,php在编译安装是要加上如下参数:
--enable-sysvsem --enable-sysvshm --enable-sysvmsg
为此,我还重新编译了php。。。。蛋疼啊。代码如下:
<?php /** * 模拟并发请求,100万次写入数据库 * 拆分为10000个进程, * 使用数据库连接池,size 为500 * */ $total = 1000; $num = 500; $per = $total/$num; $poolSize = 500; // 数据库连接池容量 $sql = ''; $child = []; // 共享内存通信 $shm_key = ftok(__FILE__,'t'); $shm_id = shm_attach($shm_key,1024,0655); const SHARE_KEY = 1; $pool = []; // 加入信号量 $sem_id = ftok(__FILE__,'s'); $signal = sem_get($sem_id); // 初始化连接数量,开始的连接数为0 shm_put_var($shm_id, SHARE_KEY,0); $begin = microtime(true); echo 'start '.$begin.PHP_EOL; for($i = 1; $i 0) { //$id = pcntl_wait($status,WNOHANG); $child[] = $pid; } else if ($pid == 0) { while(true) { // 获得信号量 sem_acquire($signal); $count = shm_get_var($shm_id, SHARE_KEY); if ($count >= $poolSize) { sem_release($signal); continue; } else { $link = mysqli_connect('localhost','root','root','yii2advanced'); if ($link) { $count++; shm_put_var($shm_id,SHARE_KEY,$count); sem_release($signal); $start = ($i-1)*$per + 1; $end = $start + $per; for($j = $start; $j $pid) { $res = pcntl_waitpid($pid, $status, WNOHANG); if ( -1 == $res || $res > 0) { unset($child[$k]); } } } $end = microtime(true); echo 'end '.$end.PHP_EOL; echo 'fork '.$num.'process insert '.$total.' recodes takes '.($end-$begin).PHP_EOL;
限 时 特 惠: 本站每日持续更新海量各大内部创业教程,一年会员只需98元,全站资源免费下载 点击查看详情
站 长 微 信: muyang-0410
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,请联系我们进行处理。