Re: File Locking
| From: | Rasmus Lerdorf | Date: | Tue, 29 Apr 2003 23:14:15 +0000 |
| Subject: | Re: File Locking | ||
| References: | 1 | Groups: | php.general |
| Request: | Send a blank email to php-general+get-145712@lists.php.net to get a copy of this message | ||
You have all sorts of issues there. First, you need to open it with mode
"r+" and not "rw".
Second, you have a race-condition between your reads and your writes.
You need to make the read and the write an atomic operation, so you can't
release the lock between the two operations since another request could
get in there and read the same value which means you will miss a count.
A nice lockless way to use a file as a counter is to simply append a
single byte to the file for every event you are counting. You can even
add some significance to that byte. For example, if you are counting web
hits, you could add a 'm' for Mozilla and an 'i' for IE so you could later
count how many requests you got from each. But the real trick with this
is that if you open a file in append mode, you do not need to lock it, and
to get the current count you simply need to call filesize().
Another way to implement a counter without worrying about locking would be
to use a database like MySQL and use its built-in atomic incrementer
abilities.
-Rasmus
On 29 Apr 2003, Brian V Bonini wrote:
> Ok, obviously I'm not understanding this whole file locking thing.
> I have this:
>
> <?php
> $counterFile = "./counter.txt";
> function displayCounter($counterFile) {
> global $counted;
> $fp = fopen($counterFile, 'rw');
> flock ($fp, LOCK_SH);
> $num = fgets($fp,7);
> flock($fp, LOCK_UN);
> if (!$counted) {
> flock($fp, LOCK_EX);
> $num += 1;
> unlink("$counterFile");
> exec("echo $num > $counterFile");
> flock($fp, LOCK_UN);
> }
> print "Visitor #$num";
> }
> if (!file_exists($counterFile)) {
> exec("echo 1 > $counterFile");
> }
> displayCounter($counterFile);
>
> /*
> following is at top of the page to not have the same visitor counted
> over and over
>
> if (!$counted) { setcookie("counted",1,time()+600); }
> */
> ?>
>
> But, I have concurrency issues with it and the counter.txt file gets
> reset to zero when it happens so I tried adding in the flock functions
> but it's not working, I'm sure I'm just using them wrong but.... Help,
> anyone? Thanks!!
>
>
>