我最熟悉的是Java、C和C++,其中有一些方法可以控制在任何给定时间只有一个线程访问资源。现在我正在寻找类似的东西,但在PHP5.x.
用一个例子来表述我的问题:
我有一个ASCII文件,它只存储一个数字,一个页面加载计数器的值。在应用程序部署时,该文件将只包含一个0。对于每次访问,该值将递增一。目标是跟踪页面加载情况。
当许多用户同时访问包含计数器的页面时,就会出现问题。当线程A读取了当前值时,假设它是11,我们称之为B的另一个线程读取该值,仍然是11。然后,第一个线程A递增读取值,在文件中写入12并关闭它。然后,第二个线程B递增读取值(11),得到12并将其写入文件。值12被存储在文件中,而它实际上应该是13。
在另一种编程语言中,我会使用互斥锁来解决这个问题。我知道模块中有互斥、共享内存和其他功能。但我想要一个能在"大多数服务器"上运行的解决方案。独立于平台。安装在大多数廉价的网络主机上。这个问题有好的解决办法吗?如果没有,如果使用数据库不是选项,您会采取哪种方式?
您可以尝试php的flock变体(http://www.php.net/flock)
我会设想类似的东西(这假设文件/tmp/counter.txt已经存在,并且在文件中有一个计数器):
<?php
$fp = fopen("/tmp/counter.txt", "r+");
echo "Attempt to lockn";
if (flock($fp, LOCK_EX)) {
echo "Lockedn";
// Read current value of the counter and increment
$cntr = fread($fp, 80);
$cntr = intval($cntr) + 1;
// Pause to prove that race condition doesn't exist
sleep(5);
// Write new value to the file
ftruncate($fp, 0);
fseek($fp, 0, SEEK_SET);
fwrite($fp, $cntr);
flock($fp, LOCK_UN); // release the lock
fclose($fp);
}
?>
PHP的flock()函数就是要走的路。但是,您必须确保对文件的所有访问都受到首先对flock()的调用的保护。PHP不会检查文件是否被锁定,除非你明确地调用它
这个概念实际上与互斥(保护共享资源等)是相同的,但它足够重要,需要特别强调。