php多进程并发,php多进程模拟并发事务

用实例代码给大家介绍关于php多进程模拟并发事务产生的一些问题,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧

数据表

drop table if exists `test`;

create table if not exists `test` (

id int not null auto_increment ,

count int default 0 ,

primary key `id` (`id`)

) engine=innodb character set utf8mb4 collate = utf8mb4_bin comment '测试表';

insert into test (`count`) values (100);

// 进程数量

$pro_count = 100;

$pids = [];

for ($i = 0; $i < $pro_count; ++$i)

{

$pid = pcntl_fork();

if ($pid < 0) {

// 主进程

throw new Exception('创建子进程失败: ' . $i);

} else if ($pid > 0) {

// 主进程

$pids[] = $pid;

} else {

// 子进程

try {

$pdo = new PDO(...);

$pdo->beginTransaction();

$stmt = $pdo->query('select `count` from test');

$count = $stmt->fetch(PDO::FETCH_ASSOC)['count'];

$count = intval($count);

if ($count > 0) {

$count--;

$pdo->query('update test set `count` = ' . $count . ' where id = 2');

}

$pdo->commit();

} catch(Exception $e) {

$pdo->rollBack();

throw $e;

}

// 退出子进程

exit;

}

}

期望的结果

期望 count 字段减少的量超过 100,变成负数!也就是多减!

实际结果

并发 200 的情况下,运行多次后的结果分别如下:

1. count = 65

2. count = 75

3. count = 55

4. count = 84

...

与期望结果相差甚远!为什么会出现这样的现象呢?

解释

首先清楚下目前的程序运行环境,并发场景。何为并发,几乎同时执行,称之为并发。具体解释如下:

进程 过程 获取 更新

1-40 同时创建并运行 100 99

41-80 同时创建并运行 99 98

81 - 100 同时创建并运行 98 97

对上述第一行做解释,第 1-40 个子进程的创建几乎同时,运行也几乎同时:

进程 1 获取 count = 100,更新 99

进程 2 获取 count = 100,更新 99

...

进程 40 获取 count = 100,更新 99

所以,实际上这些进程都做了一致的操作,并没有按照预期的那样:进程1 获取 count=100,更新 99;进程 2 获取进程1更新后的结果 count=99,更新98;...;进程 99 获取进程 98更新后的结果count=1,更新0

,产生的现象就是少减了!!

结论

采用上述做法实现的程序,库存总是 >= 0。

疑问

那要模拟超库存的场景该如何设计程序呢?

仍然采用上述代码,将以下代码:

if ($count > 0) {

$count--;

$pdo->query('update test set `count` = ' . $count . ' where id = 2');

}

修改成下面这样:

if ($count > 0) {

$pdo->query('update test set `count` = `count` - 1 where id = 2');

}

结果就会出现超库存!!

库存 100,并发 200,最终库存减少为 -63。为什么会出现这样的情况呢?以下描述了程序运行的具体过程

进程 1 获取库存 100,更新 99

进程 2 获取库存 100,更新 98(99 - 1)

进程 3 获取库存 100,更新 97(98 - 1)

....

进程 168 获取库存 1 ,更新 0(1-1)

进程 169 获取库存 1 ,更新 -1(0 - 1)

进程 170 获取库存 1 ,更新 -2(-1 - 1)

....

进程 200 获取库存 1,更新 -63(-62 - 1)

现在看来很懵逼,实际就是下面这条语句导致的:

$pdo->query('update test set `count` = `count` - 1 where id = 2');

这边详细阐述 进程 1,简称 a;进程 2,简称 b 他们具体的执行顺序:

1. a 查询到库存 100

2. b 查询到库存 100

3. a 更新库存为 99(100 - 1),这个应该秒懂

4. b 更新库存为 98(99 - 1)

- b 在执行更新操作的时候拿到的是 a 更新后的库存!

- 为什么会这样?因为更新语句是 `update test set count = count - 1 where id = 2`

以上内容希望帮助到大家,很多PHPer在进阶的时候总会遇到一些问题和瓶颈,业务代码写多了没有方向感,不知道该从那里入手去提升,对此我整理了一些资料,包括但不限于:分布式架构、高可扩展、高性能、高并发、服务器性能调优、TP6,laravel,Redis,Swoole、Swoft、Kafka、Mysql优化、shell脚本、Docker、微服务、Nginx等多个知识点高级进阶干货需要的可以免费分享给大家,需要戳这里PHP进阶架构师>>>实战视频、大厂面试文档免费获取

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/575734.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

查看数据库中有哪些活动的事务,对应的会话id,执行的语句

select dbt.database_id,DB_NAME(dbt.database_id) 数据库名,dbt.transaction_id,at.name,at.transaction_begin_time,case at.transaction_type --事务类型 when 1 then 读/写事务 when 2 then 只读事务 when 3 then 系统事务 when 4 then 分布式事务 end trans…

php xml 空格,php闭合标签输出多余空行使xml页面显示错误的处理

在PHP官方文档中&#xff0c;曾经指出最好不要再结尾添加?>结束标记。但我们编程的习惯和使用的IDE都会为我们自动建立php结束标记?>。这个标记使用在正常情况下是不影响程序的运行的。尤其在早期的php4中&#xff0c;这种标记使用不当也不会影响最后的输出。但我最近遇…

Oil Deposits

hdu1241:http://acm.hdu.edu.cn/showproblem.php?pid1241 题意&#xff1a;就是找出有多少块有石油的区域&#xff0c;就是数组中的,这边相邻指的是是周围的八个位置。 题解&#xff1a; dfs&#xff0c;从一块油田的位子开始&#xff0c;朝着与他相邻的8个方向收索&#xff…

apache配置php版本,apache配置支持多版本php

首先在apache2配置目录中建立虚拟主机配置文件如下ServerName gzshes.localhostDocumentRoot "/var/www/gzshes"DirectoryIndex index.html index.phpOptions Indexes FollowSymLinks ExecCGIAllowOverride AllRequire all granted#下面为URL静态重写环境的配置&…

php批量采集电视剧,如何通过PHP多线程批量采集下载远程网站图片代码实例

/*** curl 多线程* author http://www.lai18.com* param array $array 并行网址* param int $timeout 超时时间* return mix*/public function Curl_http($array,$timeout15){$res array();$mh curl_multi_init();//创建多个curl语柄foreach($array as $k>$url){$conn[$k]…

php asp写法,asp/php常用的库连接文件代码写法大全

今天有位朋友问到了&#xff0c;关于conn.asp文件内容&#xff0c;这里我作统一整理说明。一直以来主要写asp与php&#xff0c;所以这里只作这两种写法总结&#xff0c;常用的各类库连接文件写法。ASP&#xff1a;by:zhoz http://log.zhoz.com/ASP来说&#xff0c;首先当然是SQ…

windows_study_2

描述&#xff1a;如何确定像%ProgramFiles%这样格式的目录的具体位置&#xff1f; 解决&#xff1a;运行——cmd——echo %ProgramFiles%——回车——界面就显示出目录位置了。转载于:https://www.cnblogs.com/lishidefengchen/p/3370150.html

php 控制器分组模式,控制器分组路由

控制器分组路由目的降低控制器复杂度我有个Volunteer(自愿者)控制器&#xff0c;下面有多个子模块&#xff0c;比如&#xff1a;job、question、resume、groupapp|--cli|--m|--web| |--controller| | |--Message.php| | |--Passport.php| | |--User.php| | |--Volunteer.php如果…

WCF部署到IIS不使用svc文件

<?xml version"1.0" encoding"utf-8"?><configuration> <system.web> <compilation debug"false" targetFramework"4.0" /> </system.web> <system.serviceModel> <behaviors> …

php订阅号借权,php订阅号借权

微信订阅号显示暂时无法提供服务该怎么用&#xff1f;方法:1.首先确定您的微信公众号使用的是开发者模式&#xff0c;接口设置正确&#xff0c;并能正常收发普通消息。2.下面说一下提示"该公众号暂时无法提供服务&#xff0c;请稍候再试"这条信息的原因大家先了解一下…

java.io.FileNotFoundException:/mnt/sdcard/......(Permission denied)

今天在实现下载模块的时候&#xff0c;从服务器下载apk安装的时候总是不成功。 打开LogCat查看日志&#xff0c;发现在访问sdcard的时候出现Permission denied的情况。 百度之后发现原因是没有添加权限。 解决办法是在Manifest文件里添加&#xff1a; “<uses-permission an…

php vendor路径,php – 如何使用composer获取根包路径

我正在使用composer开发一个名为php-app-config的PHP组件.这个组件,一旦被另一个项目需要,并使用composer install安装,应该在root package的config文件夹中查找配置文件,类似于root_package / config / config.yml../config/config.yml应仅存在于根包中,而不应存在于composer.…

POJ 2253 Frogger (求某两点之间所有路径中最大边的最小值)

题意&#xff1a;有两只青蛙&#xff0c;a在第一个石头&#xff0c;b在第二个石头&#xff0c;a要到b那里去&#xff0c;每种a到b的路径中都有最大边&#xff0c;求所有这些最大边的最小值。思路&#xff1a;将所有边长存起来&#xff0c;排好序后&#xff0c;二分枚举答案。 时…

基于matlab的频率响应分析,基于MATLAB/GUI的二阶低通电路频率响应分析与仿真

第 34 卷 第 5 期 2011 年 10 月 电 子 器 件 Chinese Journal of Electron Devices Vol&#xff0e; 34 No&#xff0e; 5 Oct&#xff0e; 2011 项目来源: 基本电路的分析与综合实时演示系统( ndkf0908) 收稿日期:2011&#xff0d;04&#xff0d;19 修改日期:2011&#xff0d…

详解.NET IL代码(一)

本文主要介绍IL代码&#xff0c;内容大部分来自网上&#xff0c;进行整理合并的。 一、IL简介 为什么要了解IL代码&#xff1f; 如果想学好.NET&#xff0c;IL是必须的基础&#xff0c;IL代码是.NET运行的基础&#xff0c;当我们对运行结果有异议的时候&#xff0c;可以通过IL代…

CentOS yum安装mcrypt详细图解教程[linux]

在Linux的发行版CentOS 6.3 系统下&#xff0c;LAMP(LinuxApacheMysqlphp)环境搭建好后发现PHPMyadmin提示 “无法载入mcrypt模块” 的错误感觉很不爽&#xff0c;就尝试着使用yum安装提示找不到模块。如下为执行过程&#xff1a; [rootptr228 ~]# yum install php-mcrypt Sett…

matlab计算大米个数,如何求数组元素的个数 matlab

2016-11-21 回答比如说你的数组是a&#xff0c;那么元素个数可以这样求解&#xff1a;[m,n]size(a);numm*n例如&#xff1b;a 1 1 0 1 1 0 0 1 1 1 0 11 1 0 1 0 0 1 1 1 1 0 01 1 1 1 1 0 1 0 1 0 0 10 0 1 1 0 1 0 0 0 1 1 10 0 0 1 1 1 0 1 1 0 0 00 1 0 1 0 1 0 1 1 1 1 01…

软引用、弱引用、虚引用

阅读&#xff1a;http://sish#去掉我#uok.com/forum/posts/list/342.html 我很好奇为什么不能引用某网站的文字...... 对强弱等引用早有耳闻&#xff0c;却一直发现似乎无用武之地&#xff0c;今早看了 http://android-developers.blogspot.com/2010/07/multithreading-for-per…

matlab dll没有头文件,matlab调用dll没有头文件怎么办

2018-12-08 回答基于dll形式vc调用matlab函数方法如果在一matlab中或vc中写好了函数的话&#xff0c;想在对方的环境中使用&#xff0c;直接将对方语言的函数编译成dll是一个很方便的方法&#xff0c;不需要重写了。今天把基于dll形式vc调用matlab函数的主要过程写下&#xff0…

关于安装Ubuntu后触摸板无法使用的解决方案

安装了Ubuntu后发现触摸板无法使用&#xff0c;以为是修改了安装文件导致&#xff08;之前拿安装源文件做了小实验&#xff09;&#xff0c;于是重装&#xff0c;之后触摸板仍无法使用&#xff0c;在一个长满小广告的页面上找到了解决方案。 以下是原文章内容&#xff1a; 最近…