PHP read-write file high concurrency processing operation step Analysis

Source: Internet
Author: User
Tags flock glob php database php write
This time for everyone to bring PHP read and write files high concurrency processing operation step Analysis, PHP read and write files high concurrency processing of attention to what, the following is the actual case, together to see.

Recent company game development needs to know the game load churn rate. Because, what we do is the Web game. People who have played web games know that there are some resources to load before entering the game. Finally, the game interface to create the role is reached. We have a need to count the number of users who have not yet reached the role creation interface during the loading process.

We do statistics at the beginning of loading, and then we record the number of people after the load is complete. This way, the number of successful loads is subtracted by the number of people before loading. You know the churn rate of the load. You can know whether the game will continue to optimize the loading process, reduce the user load game rate.

As a result, our volume is from the mainstream of the co-media to guide the volume. So, concurrency is very high, and it should be roughly 1000 of the concurrent number per second.

The number of people before loading was intended to be placed in the game's internal cache platform. However, colleagues at the back of the game worry that concurrency is too high and cause resources to be wasted for no reason. Because the release of memory is not a real-time response. So, put the number of statistics on another server: the statistics server.

The scenario I just started with is as follows:

file_get_contents() file_put_contents() Read and write with PHP. The first read and write to the file to write 1, the second load on the original base plus 1. And so on. The idea of this order has no problem at all. The problem is that our servers cannot be in sequential form.

In a word, concurrent access is not sequential. When a player loads the game to read the number 100 in the file (if this is the time), the B player reads 100, at this time, processing a player's thread is on the basis of 100 plus 1, get 101, will write to the file 101.

The thread that handles the B player also gets the same result, writing 101 to the file. At this point, the problem arises? B players after a player to load the game, it should be 102 calculation results.

This is the problem caused by concurrency. This time, I thought of taking fopen() an open file and flock() adding a write lock. People will think that this approach has a lock, then it will not cause problems. In fact, it is also wrong.

Because, our problem is not out of writing. Instead, it causes the data to be out of sync when it is read. Ok. To here, I really Baidu Google have been confused.

I can only find another way to do this when I'm dreaming of the PHP function itself. Out of it. So, I think of the language map mapping mechanism. Similar to our PHP array, I add an element to the array every time I load it. So, in the end I just need count() an array to know how many players have loaded the game.

However, with arrays, there is also a problem. is the PHP variable or constant, after the execution of the script will be cleared out by itself. So, I thought about the way the file was saved.

The idea of the final feasible solution is as follows:

Open a file with fopen in a write-only manner. Then write the lock. Each time the player loads I write a number 1 to the file, and finally get the contents of the file through a single file_get_contents() read out, and then strlen() calculate the length of how many players have loaded the game.

Hearing that flock() a function is locked can cause system resources to increase over time. So, I use the way that everyone uses, with the Microsecond timeout technology to solve this problem. If I get out of this time, I'll drop it. The specific code is as follows:

The loadcount.func.php function file. /** * Gets the number of game loads for a source and a server ID. * * @param string $fromid source identification. * @param int $serverid server ID number.    * * @return int */function getloadcount ($fromid, $serverid) {global $g _global;    $serverid = (int) $serverid;    $fromid = MD5 ($FROMID); $filename = $fromid. $serverid.    '. txt ';    $data = file_get_contents ($filename); return strlen ($data);} /** * Gets the number of game loads for all servers in a source. * * @param string $fromid source identification.    * * @return int */function getallloadcount ($fromid) {global $g _global;    $fromid = MD5 ($FROMID);    $count = 0;        foreach (Glob ("{$fromid}*.txt") as $filename) {$file _content = file_get_contents ($filename);    $count + = strlen ($file _content); } return $count;} /** * Clears all loading data.    * * @return void */function clearloadcount () {foreach (Glob ("*.txt") as $filename) {unlink ($filename); } return true; /** * Delayed update of game load times middleware. * * Use this function to delay update data, principle: when less than 1000 times, do not update the database, more than 1000 to update into the database. * * @param string $fromid source identification. * @param int $serverid ServiceThe ID number of the device.    */function Delayaddloadcount ($fromid, $serverid) {//Use MD5 to generate file name record cache count.    $fromid = MD5 ($FROMID); $filename = $fromid. $serverid.    '. txt ';        if ($fp = fopen ($filename, ' a ')) {$startTime = Microtime ();            do {$canWrite = Flock ($fp, LOCK_EX);            if (! $canWrite) {usleep (round (mt_rand (0, 100) *1000));        }} while ((! $canWrite) && ((Microtime ()-$startTime) < 1000));        if ($canWrite) {fwrite ($fp, "1");    } fclose ($FP); } return true;

< php/** * @describe Platform User load Game Count interface entry. * @date 2012.12.17 */include_once './loadcount.func.php ';//test. $_get[' fromid ' = ' 4399 ';//$_get[' serverid '] = Mt_rand (0, 5);//Add load count.  if ($_get[' action '] = = ' Addcount ') {$fromid = $_get[' Fromid '];    SOURCE identification. $serverid = $_get[' ServerID ');    The server ID number.    $return = Delayaddloadcount ($fromid, $serverid); $return = $return?    1:0;    Ob_clean ();    echo Json_encode ($return); Exit;} The number of loads to take.  ElseIf ($_get[' action '] = = ' GetCount ') {$fromid = $_get[' Fromid '];    SOURCE identification.    if (!isset ($_get[' ServerID ')))//There is a server number ID that takes the server load count of the source.    {$count = Getallloadcount ($fromid);    } else//load the corresponding source number of times.        {$serverid = $_get[' ServerID ');//server ID number.    $count = Getloadcount ($fromid, $serverid);    } Ob_clean ();    Header (' Content-type:text/html;charset=utf-8 '); $serverid = strlen ($serverid)?    $serverid: ' None '; echo "Source: {$fromid}, server id:{$serverid}, Game load Count:".    $count; Exit;} Clears the load count. ElseIf ($_get[' actIon '] = = ' Clearcount ') {header (' content-type:text/html;charset=utf-8 ');    $return = Clearloadcount (); if ($return) {echo ' clears successfully!    "; } else {echo ' purge failed!    "; }}

This is the lesson of blood, so I have to record it down. For others to learn from later.

This article is the author of Ice a year ago in 4399 Game Studios responsible for doing data analysis when writing code. We hope to help you.

High concurrent instances of PHP database operation

High concurrency under PHP write file log loss

<?php/** * Created by Phpstorm.  * User:andyfeng * date:2015/6/24 * time:13:31 */class logfileutil {public static $fileHandlerCache;  private static $initFlag = false;  private static $MAX _loop_count = 3;    private static function init () {self:: $initFlag = true;  Register_shutdown_function (Array ("Logfileutil", "Shutdown_func")); /** * Output to file log * @param $filePath file path * @param $msg log information * @return int */public static function out ($filePa    Th, $msg) {if (!self:: $initFlag) {self::init ();  } return Self::internalout ($filePath, $msg); }/** * @param $filePath * @param $msg * @param $loop * @return int */private static function Internalout ($fi    Lepath, $msg, $loop = 0) {//In case a failure has been added to cause a dead loop if ($loop > Self:: $MAX _loop_count) {$result = 0;      } else {$loop + +;      $fp = self:: $fileHandlerCache ["$filePath"];        if (empty ($fp)) {$fp = fopen ($filePath, "A +");      Self:: $fileHandlerCache [$filePath] = $fp;     } if (Flock ($FP, lock_ex)) {$result = Fwrite ($fp, $msg);      Flock ($FP, lock_un);      } else {$result = Self::internalout ($filePath, $msg, $loop);  }} return $result; } function Shutdown_func () {if (!empty (logfileutil:: $fileHandlerCache)) {if (Is_array (logfileutil:: $fileHandler Cache) {foreach (Logfileutil:: $fileHandlerCache as $k = + $v) {if (Is_resource ($v))//file            _put_contents ("Close.txt", $k);        Fclose ($v); }      }    }  }}

Believe that you have read the case of this article you have mastered the method, more exciting please pay attention to the PHP Chinese network other related articles!

Recommended reading:

PHP dynamic XML Document creation steps

How PHP can quickly generate unlimited classes (with code)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.