php 使用多进程批量插入数据
2023-09-14 08:56:55 时间
多进程使用场景
多进程一般用来处理消息队列,等数据量比大的任务。
使用限制
php多进程需要pcntl
和posix
扩展支持。可以使用php -m
查看是否安装该扩展。
需要注意的是CLI模式和CGI模式时用的php.ini并非同一个配置,需要单独配置。一般情况下使用默认配置即可
php多进程只能运行在CLI环境下,在web服务器环境下会出现无法预期的结果,要慎用!
子进程的个数最好和服务器的核数匹配,子进程超过cpu核数就会存在执行分配问题,所以不建议子进程开得很多。
核心函数
pcntl_fork
:
创建子进程,一次调用两次返回。在父进程中返回子进程id,在子进程中返回0,创建子进程失败返回-1。所以可以根据返回值判断当前是处于子进程或父进程。pcntl_waitpid
:
等待或返回fork的子进程状态,具体参数可以参考文档
扩展知识
僵尸进程:当子进程比父进程先结束,而父进程又没有回收子进程,释放子进程占用的资源,此时子进程将成为一个僵尸进程。
孤儿进程:是指其父进程执行完成或被终止后仍继续运行的一类进程。这些孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。
守护进程:在后台运行的特殊进程,用于执行特定的系统任务。很多守护进程在系统引导的时候启动,并且一直运行直到系统关闭。另一些只在需要的时候才启动,完成任务后就自动结束。
php版本 注:要有pcntl扩展(php -m查询是否有此扩展)
mysql 数据库(test1) 数据表
CREATE TABLE `test1` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(50) NOT NULL DEFAULT '', `create_time` datetime NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=90001 DEFAULT CHARSET=utf8mb4;
具体代码:
<?php
class TestController { private $pid_num = 5;//进程数 /** * 等待进程结束 */ public function wait() { //等待子进程结束 while (pcntl_waitpid(0, $status) != -1) { echo "子进程结束了" . PHP_EOL; } } /** * 插入数据 * @param $fpid * @param $cpid */ public function runSql($fpid, $cpid) { $link = mysqli_connect('127.0.0.1:3306', 'root', '123456', 'test'); for ($j = 0; $j < 2000; $j++) { $time = date('Y-m-d H:i:s', time()); $sqlTpl = 'INSERT INTO `%s` (`name`,`create_time`) VALUES ("%s", "%s")'; $name = "fpid:{$fpid},cpid:{$cpid},j:{$j}"; $table = 'test1'; $sql = sprintf($sqlTpl, $table, $name, $time); mysqli_query($link, $sql); } mysqli_close($link); } /** * 拆分为5个进程,每个进程处理2000条插入 */ public function actionTest() { if (!function_exists("pcntl_fork")) { die("pcntl extention is must !"); } declare (ticks=1); $start_time = date('Y-m-d H:i:s', time()); for ($i = 0; $i < $this->pid_num; $i++) { $pid = pcntl_fork(); //创建一个子进程 if ($pid > 0) { //主进程代码 //父进程获取自己的进程id $fpid = posix_getpid(); // echo "父进程--" . $fpid . PHP_EOL; cli_set_process_title("我是父进程,我的进程id是{$fpid}."); // sleep(5); } else if ($pid == 0) { //子进程代码 //子进程获取自己的进程id $cpid = posix_getpid(); //获取当前进程id $fpid = posix_getppid(); //获取父进程id echo "父进程--{$fpid}子进程--" . $cpid . PHP_EOL; cli_set_process_title("我是{$fpid}的子进程,我的进程id是{$cpid}."); $this->runSql($fpid, $cpid); // sleep(2); exit(0); //子进程执行完自己的任务后,退出 } else { //创建失败 echo "创建子进程失败", PHP_EOL; break; } } $this->wait(); //所有子进程结束 echo "父进程结束" . PHP_EOL; $end_time = date('Y-m-d H:i:s', time()); echo "开始时间{$start_time},结束时间{$end_time}" . PHP_EOL; } }
相关文章
- php 对象转json_php json解析
- php manager + mariadb/mysql + iis windows server 配置Discuz X3.5
- PHP addslashes()和stripslashes():字符串转义与还原
- [PHP] PHP请求Socket接口测试详解编程语言
- MySQL在PHP中的配置须知(php中的mysql配置)
- PHP扩展开发:实现Redis读写数据(php扩展redis)
- 器使用Linux下的PHP编辑器快速提升编程能力(linuxphp编辑)
- 使用PHP快速实现MySQL查询(php实现mysql查询)
- PHP与Redis出色的结合(php连redis)
- PHP中的MySQL转义码简介(php转义mysql)
- PHP操作MySQL数据库的完整指南(php读写mysql)
- PHP实现Oracle数据库连接(php支持oracle)
- PHP Redis实时监控系统的应用(php redis 监控)
- 从PHP到MSSQL:实现高效转换(php转换mssql)
- 驱动PHP无法找到MSSQL驱动解决方案(php 找不到mssql)
- PHP如何开启MSSQL支持?(php怎么开启mssql)
- 使用PHP 驱动MSSQL支撑稳固的开发环境(php mssql 驱动)
- 基于 PHP 和 MSSQL 的连接类开发实战(php mssql连接类)
- PHP如何正确配置MongoDB数据库连接?(php配置mongodb)
- PHP与MySQL实现无缝连接(php mysql 连接)
- Linux下查看 PHP 进程信息(linux查看php进程)
- 内存Redis自动优化PHP内存管理(redis自动释放php)
- 怎样在PHP中通过ADO调用Asscess数据库和COM程序
- PHP设计模式之观察者模式介绍
- PHP获取http请求的头信息实现步骤
- PHP实现货币换算的方法
- php批量删除cookie的简单实现方法
- php设计模式之简单工厂模式详解