PHP互斥(互斥) [英] PHP mutual exclusion (mutex)

查看:154
本文介绍了PHP互斥(互斥)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

阅读一些有关锁定PHP的文字.
它们主要直接指向 http://php.net/manual/en/function. flock.php .

Read some texts about locking in PHP.
They all, mainly, direct to http://php.net/manual/en/function.flock.php .

本页讨论有关在硬盘上打开文件的问题!

This page talks about opening a file on the hard-disk!!

真的是这样吗?我的意思是,这使锁定变得非常昂贵-这意味着每次要锁定时,我都必须访问硬盘)=

Is it really so? I mean, this makes locking really expensive - it means each time I want to lock I'll have to access the hard-disk )=

能再给我一个令人愉快的消息安慰我吗?

Can anymore comfort me with a delightful news?

由于我收到了一些答复,我想问这个问题;
我的脚本只能由一个或多个线程运行?因为如果是一个,那么我显然不需要互斥体.有一个简洁的答案吗?

Due to some replies I've got here, I want to ask this;
My script will run only by one thread, or several? Because if it's by one then I obviously don't need a mutex. Is there a concise answer?

我到底想做什么

由ircmaxell询问.
这是故事:

Asked by ircmaxell.
This is the story:

我有两个ftp服务器.我希望能够在我的网站上显示有多少在线用户在线.
因此,我认为这些ftp服务器会将其统计信息"POST"到某个PHP脚本页面.假设此页面的URL是" http://mydomain.com/update.php ".

I have two ftp servers. I want to be able to show at my website how many online users are online.
So, I thought that these ftp servers will "POST" their stats to a certain PHP script page. Let's assume that the URL of this page is "http://mydomain.com/update.php".

在网站的主页上(" http://mydomain.com/index.php ")我将显示累积统计信息(在线用户).

On the website's main page ("http://mydomain.com/index.php") I will display the cumulative statistics (online users).

就是这样.

我的问题是,我不确定一台ftp服务器是否更新其统计信息,而另一台ftp服务器也更新统计信息时,
就像多线程时一样;两个线程同时增加一些"int"变量.除非您在它们之间进行同步,否则将不会按预期发生.
那我有问题吗?是的,不是吗?

My problem is that I'm not sure if, when one ftp server updates his stats while another does it too, the info will get mixed.
Like when multi-threading; Two threads increase some "int" variable at the same time. It will not happen as expected unless you sync between them.
So, will I have a problem? Yes, no, maybe?

可能的解决方案

整天都在认真思考,我在这里有个主意,希望您能提出您的看法.
如前所述,这些ftp服务器将每60秒发布一次其统计信息.
我正在考虑使用此文件"stats.php".
它将包含在ftp服务器转到的更新脚本("update.php")和"index.php"页面上,在此页面中,访问者可以看到有多少用户在线.
现在,当ftp服务器更新时,位于"update.php"的脚本将使用新的累积统计信息修改"stats.php".
首先它将读取"stats.php"中包含的统计信息,然后进行累积,然后重写该文件.

Thinking hard about it all day long, I have an idea here and I want you to give your opinion.
As said these ftp servers will post their stats, once every 60sec.
I'm thinking about having this file "stats.php".
It will be included at the updating script that the ftp servers go to ("update.php") and at the "index.php" page where visitors see how many users are online.
Now, when an ftp server updates, the script at "update.php" will modify "stats.php" with the new cumulative statistics.
First it will read the stats included at "stats.php", then accumulate, and then rewrite that file.

如果我没记错的话,PHP将检测到文件("stats.php")已更改并加载了新文件.正确吗?

If I'm not mistaken PHP will detect that the file ("stats.php") is changed and load the new one. Correct?

推荐答案

好吧,大多数PHP在不同的进程空间中运行(几乎没有线程实现).容易的是羊群.保证可以在所有平台上使用.

Well, most of PHP runs in a different process space (there are few threading implementations). The easy one is flock. It's guaranteed to work on all platforms.

但是,如果您在支持中进行编译,则可以使用其他一些东西,例如信号量扩展. (使用--enable-sysvsem编译PHP).然后,您可以执行类似的操作(请注意,sem_acquire()应该阻止.但是如果由于某些原因而无法执行,则它将返回false):

However, if you compile in support, you can use a few other things such as the Semaphore extension. (Compile PHP with --enable-sysvsem). Then, you can do something like (note, sem_acquire() should block. But if it can't for some reason, it will return false):

$sem = sem_get(1234, 1);
if (sem_acquire($sem)) {
    //successful lock, go ahead
    sem_release($sem);
} else {
    //Something went wrong...
}

您拥有的其他选项是MySQL 用户级别锁 GET_LOCK('name', 'timeout'),或使用APC或XCache之类的东西创建您自己的锁(注意,这不是真正的锁,因为可以在其他人在您的支票和付款之间获得锁的情况下创建竞争条件接受锁).

The other options that you have, are MySQL user level locks GET_LOCK('name', 'timeout'), or creating your own using something like APC or XCache (Note, this wouldn't be a true lock, since race conditions could be created where someone else gets a lock between your check and acceptance of the lock).

要回答您编辑过的问题:

这完全取决于您的服务器配置. PHP可能是多线程运行的(每个请求由不同的线程处理),也可能是多进程运行的(每个请求由不同的进程处理).一切都取决于您的服务器配置...

It all depends on your server configuration. PHP May be run multi-threaded (where each request is served by a different thread), or it may be run multi-process (where each request is served by a different process). It all depends on your server configuration...

很少有PHP可以串行服务所有请求,而只有一个进程(和一个线程)可以满足所有请求.如果您使用的是CGI,则默认情况下它是多进程的.如果您使用的是FastCGI,则可能是多进程和多线程的.如果您在Apache上使用mod_php,则取决于工作程序类型:

It's VERY rare that PHP will serve all requests serially, with only one process (and one thread) serving all requests. If you're using CGI, then it's multi-process by default. If you're using FastCGI, it's likely multi-process and multi-thread. If you're using mod_php with Apache, then it depends on the worker type:

  1. mpm_worker将是多进程和多线程的,进程数由ServerLimit变量决定.
  2. prefork将是多进程的
  3. perchild也将是多进程的

要回答您的第二个编辑问题:

这很容易.将其存储在文件中:

It's quite easy. Store it in a file:

function readStatus() {
    $f = fopen('/path/to/myfile', 'r');
    if (!$f) return false;
    if (flock($f, LOCK_SH)) {
        $ret = fread($f, 8192);
        flock($f, LOCK_UN);
        fclose($f);
        return $ret;
    }
    fclose($f);
    return false;
}

function updateStatus($new) {
    $f = fopen('/path/to/myfile', 'w');
    if (!$f) return false;
    if (flock($f, LOCK_EX)) {
        ftruncate($f, 0);
        fwrite($f, $new);
        flock($f, LOCK_UN);
        fclose($f);
        return true;
    }
    fclose($f);
    return false;
}

function incrementStatus() {
    $f = fopen('/path/to/myfile', 'rw');
    if (!$f) return false;
    if (flock($f, LOCK_EX)) {
        $current = fread($f, 8192);
        $current++;
        ftruncate($f, 0);
        fwrite($f, $current);
        flock($f, LOCK_UN);
        fclose($f);
        return true;
    }
    fclose($f);
    return false;
}

这篇关于PHP互斥(互斥)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆