本人前一遍blog中提到,当进程数过多时,多进程插入mysql数据库表,超过了mysql最大连接数,就会报错,插入就会有失败的情况。想通过进程间通信来控制一下连接数,参考了一些网上的blog

实现了一下,利用共享内存来存放mysql的连接数,当某个进程在获取信号量后,尝试去连接数据库之前,先判断一下,当前的连接数是否超过了预定的阈值,如果没有,就连接数据库,连接成功后,连接数加一,立马释放信号,等操作数据库完毕后,进程再次阻塞,来获取信号,然后把连接数减一,释放信号量后,进程退出。

这样就可以控制有mysql的连接数不会达到上限,程序不会出现连接数据库失败的情况。当然我可以直接少fork一些进程,本人就是觉得要折腾一下。不然进程通信就懵逼了。而且也不会有以下的问题出现。

但是本人实验,fork一万个子进程,虚拟机很容易就挂了。后来该为fork 5000个子进程,插入一百万条数据,模拟的是最原始的插入。虚拟机虽然没有崩, 但是很卡,期间会出现很多僵尸进程,这里有点疑问。

多进程耗内存比较严重,下一步打算用多线程来试试。

ps:要支持Semaphore函数,php在编译安装是要加上如下参数:

--enable-sysvsem

--enable-sysvshm

--enable-sysvmsg

为此,我还重新编译了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<= $num; $i++)

{

$pid = pcntl_fork();

if($pid == -1) {

die('fork error');

}

if($pid > 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< $end; $j++){

$time = microtime(true);

$sql = 'insert pcntl_test (rank,time) values ('.$j.','.$time.')';

mysqli_query($link,$sql);

}

mysqli_close($link);

break;

}

}

sleep(1);

}

sem_acquire($signal);

$count = shm_get_var($shm_id,SHARE_KEY);

$count--;

shm_put_var($shm_id, SHARE_KEY, $count);

sem_release($signal);

$id = getmypid();

$count++;

echo 'count : '.$count.' child '.$id.' finished '.microtime(true).PHP_EOL;

exit(0);

}

}

while(count($child)){

foreach($child as $k => $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;

最后,我统计分析了一下5千个进程,一百万条记录,插入时,mysql的连接数情况(平均连接数为464),用python作图如下:

php多线程 mysql_php通过共享内存,控制mysql连接数,多进程插入数据(pcnt学习四)...相关推荐

  1. mysql常见问题处理-插入数据error code:1206

    mysql常见问题处理-插入数据error code:1206 mysql  error code:1206 the total number of locks exceeds the lock ta ...

  2. mysql为什么不能插入数据_mysql为啥不能插入数据

    mysql为何不能插入数据? 安装AppServ后首次使用mysql,没有图形界面,在"MySql Command Line Client"的操作如下: ============= ...

  3. mysql数据库表插入数据

    如何向mysql数据表中插入数据? 答:你可以通过 mysql> 命令提示窗口中向数据表中插入数据,或者通过PHP脚本来插入数据. 以下为向MySQL数据表插入数据通用的 INSERT INTO ...

  4. php怎么插入数据,利用PHP怎么向MySQL数据库中插入数据

    利用PHP怎么向MySQL数据库中插入数据 发布时间:2020-12-11 16:41:47 来源:亿速云 阅读:89 作者:Leah 这篇文章给大家介绍利用PHP怎么向MySQL数据库中插入数据,内 ...

  5. MySQL如何快速插入数据

    前言: 日常学习和工作中,经常会遇到导数据的需求.比如数据迁移.数据恢复.新建从库等,这些操作可能都会涉及大量数据的导入 有时候导入进度慢,电脑风扇狂转真的很让人崩溃,其实有些小技巧是可以让导入更快速 ...

  6. mysql怎样循环插入数据_你向 Mysql 数据库插入 100w 条数据用了多久?

    多线程插入(单表) 多线程插入(多表) 预处理SQL 多值插入SQL 事务(N条提交一次) 多线程插入(单表) 问:为何对同一个表的插入多线程会比单线程快?同一时间对一个表的写操作不应该是独占的吗? ...

  7. egg --- 配置连接mysql 创建模型 插入数据

    在egg中使用egg-sequelize插件 sequelize是与数据库操作相关的库 安装: npm install --save egg-sequelize mysql2 在egg中配置seque ...

  8. 解决MySQL删除和插入数据很慢的问题

    推荐阅读 Helm3(K8S 资源对象管理工具)视频教程:https://edu.csdn.net/course/detail/32506 Helm3(K8S 资源对象管理工具)博客专栏:https: ...

  9. mysql innodb myisam 插入数据_mysql innodb换成myisam后插入数据变快?

    myisam没有事务支持,它的连续的插入和查询速度都比Innodb快很多,但是如果需要插入和查询穿插着来,那么myisam是表锁,innodb是行锁,innodb的并发性好,并且innodb是支持事务 ...

最新文章

  1. 如果在CSDN博文编辑状态下获得博文最终网络链接?
  2. GHOST_XP详细制作过程
  3. 在 emu8086 中学习汇编In,Out指令
  4. C语言技巧之长度为0的数组
  5. 动手实现一个 localcache - 设计篇
  6. 从根儿上理解mysql_从根儿上理解 MySQL - 页总结
  7. arm 交叉编译找不到so_嵌入式杂谈之交叉编译
  8. LeetCode 1080. 根到叶路径上的不足节点(递归)
  9. Ubuntu下如何将普通用户提升到root权限
  10. Mac 安装 homebrew 流程 以及 停在 Updating Homebrew等 常见错误解决方法
  11. Deepin Linux 15.10 发布
  12. 简易封装手机浏览器touch事件
  13. C++中数组、链表list、容器map/vector的区别
  14. 写给自己,关于对纯技术的追求,以及为了金钱与前途的技术追求
  15. android写一个遥控器界面,遥控器界面软件的设计 - 基于安卓系统手机WiFi的家用智能遥控器开发...
  16. 设计模式学习 - 观察者模式
  17. cve_2019_0708 bluekeep复现踩坑
  18. 网络故障排除的五个简单步骤
  19. EPON+EOC 大批量设备网管解决方案
  20. 触须避障程序(改进篇)

热门文章

  1. Android draw9patch点九图常识
  2. ListView数据项隔行换色控制实现详解
  3. 动态路由器与静态路由器的理论知识
  4. IT风险的防控水平是一个“木桶”原理
  5. groupby elasticsearch
  6. 利用webpack和vue实现组件化
  7. 高级工程考试通过总结
  8. angular ngClick 阻止冒泡和默认行为
  9. 『第26天』Sunos (一)
  10. commons-lang StringUtils#split的坑