当前位置: 首页 > 面试题库 >

PHP互斥(互斥)

司马宏邈
2023-03-14
问题内容

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

本页讨论如何在硬盘上打开文件!

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

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

编辑:

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

我到底想做什么

ircmaxell询问。
这是故事:

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

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

而已。

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

可能的解决方案

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

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


问题答案:

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

但是,如果在支持方面进行编译,则可以使用其他一些功能,例如信号量扩展。(使用–enable-
sysvsem编译PHP)。然后,您可以执行类似的操作(请注意,sem_acquire()应该阻止。但是如果由于某些原因而无法执行操作,它将返回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之类的东西创建自己的锁(注意,这不是真正的锁,因为可以在其他人在两次检查之间获得锁的情况下创建竞争条件并接受锁)。

编辑:要回答您编辑过的问题:

这完全取决于您的服务器配置。PHP可以运行多线程(每个请求由不同的线程处理),也可以运行多进程(每个请求由不同的进程处理)。这完全取决于您的服务器配置…

PHP只能连续处理所有请求,而只有一个进程(和一个线程)处理所有请求,这是非常罕见的。如果您使用的是CGI,则默认情况下它是多进程的。如果您使用的是FastCGI,则可能是多进程和多线程。如果您在Apache上使用mod_php,则取决于工作程序类型:

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

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

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

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;
}


 类似资料:
  • 互斥是多线程系统中用于控制访问的一个原对象(primitive object)。下面的例子给出了它最基本的用法: std::mutex m; int sh; //共享数据 // … m.lock(); // 对共享数据进行操作: sh += 1; m.unlock(); 在任何时刻,最多只能有一个线程执行到lock()和unlock()之间的区域(通常称为临界区)。当第一个线程正在临界区执行时

  • Go语言包中的 sync 包提供了两种锁类型:sync.Mutex 和 sync.RWMutex。 Mutex 是最简单的一种锁类型,同时也比较暴力,当一个 goroutine 获得了 Mutex 后,其他 goroutine 就只能乖乖等到这个 goroutine 释放该 Mutex。 RWMutex 相对友好些,是经典的单写多读模型。在读锁占用的情况下,会阻止写,但不阻止读,也就是多个 gor

  • 上面的例子中,我们看过了如何在多个协程之间原子地访问计数器,对于更复杂的例子,我们可以使用Mutex来在多个协程之间安全地访问数据。 package main import ( "fmt" "math/rand" "runtime" "sync" "sync/atomic" "time" ) func main() { // 这个例子的状态就

  • 线程使用互斥量保护共享资源 线程使用互斥量保护共享资源 源码/* * Copyright (c) 2006-2018, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2018-08-24 yangjie the first versi

  • 互斥量接口 结构体 struct   rt_mutex   互斥量控制块 更多...   类型定义 typedef struct rt_mutex *  rt_mutex_t   互斥量类型指针定义   函数 rt_err_t  rt_mutex_init (rt_mutex_t mutex, const char *name, rt_uint8_t flag)   初始化互斥量   rt_err

  • Introduction This is the fourth part of the chapter which describes synchronization primitives in the Linux kernel and in the previous parts we finished to consider different types spinlocks and semap