search
HomeBackend DevelopmentPHP TutorialShare solutions to several PHP concurrency scenarios

Share solutions to several PHP concurrency scenarios

In concurrent scenarios such as flash sales and rush sales, overselling may occur. There is no native concurrency solution in the PHP language, so other methods are needed to achieve it. Concurrency control.

The common solutions listed are:

Use a queue, set up an extra process to handle the queue, and put all concurrent requests into the queue, which will be processed serially by the extra process. , the concurrency problem does not exist, but it requires additional process support and serious processing delays. This article will not discuss this method first.

Use the transaction characteristics of the database to perform atomic updates. This method needs to rely on the transaction characteristics of the database.

With the help of file exclusive lock, when processing an order request, use flock to lock a file. Only those who successfully obtain the lock can process the order.

1. Utilize Redis transaction features

Redis transactions are atomic operations, which can ensure that the data is not modified by other concurrent processes during order processing.

Sample code:

<?php
$http = new swoole_http_server("0.0.0.0", 9509);   // 监听 9509
$http->set(array(
 &#39;reactor_num&#39; => 2,  //reactor thread num
 &#39;worker_num&#39; => 4    //worker process num
));
$http->on(&#39;request&#39;, function (swoole_http_request $request, swoole_http_response $response) {
 $uniqid = uniqid(&#39;uid-&#39;, TRUE);    // 模拟唯一用户ID
 $redis = new Redis();
 $redis->connect(&#39;127.0.0.1&#39;, 6379);    // 连接 redis
 $redis->watch(&#39;rest_count&#39;);  // 监测 rest_count 是否被其它的进程更改
 $rest_count = intval($redis->get("rest_count"));  // 模拟唯一订单ID
 if ($rest_count > 0){
 $value = "{$rest_count}-{$uniqid}";  // 表示当前订单,被当前用户抢到了
 // do something ... 主要是模拟用户抢到单后可能要进行的一些密集运算
 $rand = rand(100, 1000000);
 $sum = 0;
 for ($i = 0; $i < $rand; $i++) {$sum += $i;}
 // redis 事务
 $redis->multi();
 $redis->lPush(&#39;uniqids&#39;, $value);
 $redis->decr(&#39;rest_count&#39;);
 $replies = $redis->exec();  // 执行以上 redis 事务
 // 如果 rest_count 的值被其它的并发进程更改了,以上事务将回滚
 if (!$replies) {
 echo "订单 {$value} 回滚" . PHP_EOL;
 }
 }
 $redis->unwatch();
});
$http->start();

Use ab test

$ ab -t 20 -c 10 http://192.168.1.104:9509/

2. Use file exclusive lock (blocking mode)

In blocking mode, if a process acquires a file exclusive lock while other processes are occupying the lock, the process will hang up and wait for other processes to release the lock, acquire the lock itself, and then proceed.

Sample code:

<?php
$http = new swoole_http_server("0.0.0.0", 9510);
$http->set(array(
 &#39;reactor_num&#39; => 2,  //reactor thread num
 &#39;worker_num&#39; => 4    //worker process num
));
$http->on(&#39;request&#39;, function (swoole_http_request $request, swoole_http_response $response) {
 $uniqid = uniqid(&#39;uid-&#39;, TRUE);
 $redis = new Redis();
 $redis->connect(&#39;127.0.0.1&#39;, 6379);
 $fp = fopen("lock.txt", "w+");
 // 阻塞(等待)模式, 要取得独占锁定(写入的程序)
 if (flock($fp,LOCK_EX)) {  //锁定当前指针
 // 成功取得锁后,放心处理订单
 $rest_count = intval($redis->get("rest_count"));
 $value = "{$rest_count}-{$uniqid}";
 if ($rest_count > 0) {
 // do something ...
 $rand = rand(100, 1000000);
 $sum = 0;
 for ($i = 0; $i < $rand; $i++) {$sum += $i;}
 $redis->lPush(&#39;uniqids&#39;, $value);
 $redis->decr(&#39;rest_count&#39;);
 }
 // 订单处理完成后,再释放锁
 flock($fp, LOCK_UN);
 }
 fclose($fp);
});
$http->start();

Use ab test

$ ab -t 20 -c 10 http://192.168.1.104:9510/

3. Use file exclusive lock (non-blocking mode)

Non In blocking mode, if a process acquires a file exclusive lock while other processes are occupying the lock, the process will immediately determine that acquiring the lock failed and continue execution. \

Sample code:

<?php
$http = new swoole_http_server("0.0.0.0", 9511);
$http->set(array(
 &#39;reactor_num&#39; => 2,  //reactor thread num
 &#39;worker_num&#39; => 4    //worker process num
));
$http->on(&#39;request&#39;, function (swoole_http_request $request, swoole_http_response $response) {
 $uniqid = uniqid(&#39;uid-&#39;, TRUE);
 $redis = new Redis();
 $redis->connect(&#39;127.0.0.1&#39;, 6379);
 $fp = fopen("lock.txt", "w+");
 // 非阻塞模式, 如果不希望 flock() 在锁定时堵塞,则给 lock 加上 LOCK_NB
 if(flock($fp,LOCK_EX | LOCK_NB))   //锁定当前指针
 {
 // 成功取得锁后,放心处理订单
 $rest_count = intval($redis->get("rest_count"));
 $value = "{$rest_count}-{$uniqid}";
 if($rest_count > 0){
 // do something ...
 $rand = rand(100, 1000000);
 $sum=0;
 for ($i=0;$i<$rand;$i++){ $sum+=$i; }
 $redis->lPush(&#39;uniqids&#39;, $value);
 $redis->decr(&#39;rest_count&#39;);
 }
 // 订单处理完成后,再释放锁
 flock($fp,LOCK_UN);
 } else {
 // 如果获取锁失败,马上进入这里执行
 echo "{$uniqid} - 系统繁忙,请稍后再试".PHP_EOL;
 }
 fclose($fp);
});
$http->start();

Use ab test

$ ab -t 20 -c 10 http://192.168.1.104:9511/

Finally, the test result comparison of the three processing methods is given

redis transaction mode:

......
Concurrency Level:      10
Time taken for tests:   20.005 seconds
Complete requests:      17537
Failed requests:        0
Total transferred:      2578380 bytes
HTML transferred:       0 bytes
Requests per second:    876.62 [#/sec] (mean)
Time per request:       11.407 [ms] (mean)
Time per request:       1.141 [ms] (mean, across all concurrent requests)
Transfer rate:          125.86 [Kbytes/sec] received
......

File exclusive lock (blocking mode):

......
Concurrency Level:      10
Time taken for tests:   20.003 seconds
Complete requests:      8205
Failed requests:        0
Total transferred:      1206282 bytes
HTML transferred:       0 bytes
Requests per second:    410.19 [#/sec] (mean)
Time per request:       24.379 [ms] (mean)
Time per request:       2.438 [ms] (mean, across all concurrent requests)
Transfer rate:          58.89 [Kbytes/sec] received
......

File exclusive lock (non-blocking mode):

......
Concurrency Level:      10
Time taken for tests:   20.002 seconds
Complete requests:      8616
Failed requests:        0
Total transferred:      1266846 bytes
HTML transferred:       0 bytes
Requests per second:    430.77 [#/sec] (mean)
Time per request:       23.214 [ms] (mean)
Time per request:       2.321 [ms] (mean, across all concurrent requests)
Transfer rate:          61.85 [Kbytes/sec] received
......

After comparing the test results, redis transaction mode It is better than the file exclusive locking mode, and in the file exclusive locking mode, the non-blocking mode is better than the blocking mode.

Related tutorial recommendations: "PHP Tutorial"

The above is the detailed content of Share solutions to several PHP concurrency scenarios. For more information, please follow other related articles on the PHP Chinese website!

Statement
This article is reproduced at:博客园. If there is any infringement, please contact admin@php.cn delete
Beyond the Hype: Assessing PHP's Role TodayBeyond the Hype: Assessing PHP's Role TodayApr 12, 2025 am 12:17 AM

PHP remains a powerful and widely used tool in modern programming, especially in the field of web development. 1) PHP is easy to use and seamlessly integrated with databases, and is the first choice for many developers. 2) It supports dynamic content generation and object-oriented programming, suitable for quickly creating and maintaining websites. 3) PHP's performance can be improved by caching and optimizing database queries, and its extensive community and rich ecosystem make it still important in today's technology stack.

What are Weak References in PHP and when are they useful?What are Weak References in PHP and when are they useful?Apr 12, 2025 am 12:13 AM

In PHP, weak references are implemented through the WeakReference class and will not prevent the garbage collector from reclaiming objects. Weak references are suitable for scenarios such as caching systems and event listeners. It should be noted that it cannot guarantee the survival of objects and that garbage collection may be delayed.

Explain the __invoke magic method in PHP.Explain the __invoke magic method in PHP.Apr 12, 2025 am 12:07 AM

The \_\_invoke method allows objects to be called like functions. 1. Define the \_\_invoke method so that the object can be called. 2. When using the $obj(...) syntax, PHP will execute the \_\_invoke method. 3. Suitable for scenarios such as logging and calculator, improving code flexibility and readability.

Explain Fibers in PHP 8.1 for concurrency.Explain Fibers in PHP 8.1 for concurrency.Apr 12, 2025 am 12:05 AM

Fibers was introduced in PHP8.1, improving concurrent processing capabilities. 1) Fibers is a lightweight concurrency model similar to coroutines. 2) They allow developers to manually control the execution flow of tasks and are suitable for handling I/O-intensive tasks. 3) Using Fibers can write more efficient and responsive code.

The PHP Community: Resources, Support, and DevelopmentThe PHP Community: Resources, Support, and DevelopmentApr 12, 2025 am 12:04 AM

The PHP community provides rich resources and support to help developers grow. 1) Resources include official documentation, tutorials, blogs and open source projects such as Laravel and Symfony. 2) Support can be obtained through StackOverflow, Reddit and Slack channels. 3) Development trends can be learned by following RFC. 4) Integration into the community can be achieved through active participation, contribution to code and learning sharing.

PHP vs. Python: Understanding the DifferencesPHP vs. Python: Understanding the DifferencesApr 11, 2025 am 12:15 AM

PHP and Python each have their own advantages, and the choice should be based on project requirements. 1.PHP is suitable for web development, with simple syntax and high execution efficiency. 2. Python is suitable for data science and machine learning, with concise syntax and rich libraries.

PHP: Is It Dying or Simply Adapting?PHP: Is It Dying or Simply Adapting?Apr 11, 2025 am 12:13 AM

PHP is not dying, but constantly adapting and evolving. 1) PHP has undergone multiple version iterations since 1994 to adapt to new technology trends. 2) It is currently widely used in e-commerce, content management systems and other fields. 3) PHP8 introduces JIT compiler and other functions to improve performance and modernization. 4) Use OPcache and follow PSR-12 standards to optimize performance and code quality.

The Future of PHP: Adaptations and InnovationsThe Future of PHP: Adaptations and InnovationsApr 11, 2025 am 12:01 AM

The future of PHP will be achieved by adapting to new technology trends and introducing innovative features: 1) Adapting to cloud computing, containerization and microservice architectures, supporting Docker and Kubernetes; 2) introducing JIT compilers and enumeration types to improve performance and data processing efficiency; 3) Continuously optimize performance and promote best practices.

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
3 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Best Graphic Settings
3 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. How to Fix Audio if You Can't Hear Anyone
3 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: How To Unlock Everything In MyRise
3 weeks agoBy尊渡假赌尊渡假赌尊渡假赌

Hot Tools

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

This project is in the process of being migrated to osdn.net/projects/mingw, you can continue to follow us there. MinGW: A native Windows port of the GNU Compiler Collection (GCC), freely distributable import libraries and header files for building native Windows applications; includes extensions to the MSVC runtime to support C99 functionality. All MinGW software can run on 64-bit Windows platforms.

PhpStorm Mac version

PhpStorm Mac version

The latest (2018.2.1) professional PHP integrated development tool

SublimeText3 Linux new version

SublimeText3 Linux new version

SublimeText3 Linux latest version

SecLists

SecLists

SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.

Atom editor mac version download

Atom editor mac version download

The most popular open source editor