如何在PHP中同步多个进程以模拟wait()/notifyAll()

如何在PHP中同步多个进程以模拟wait()/notifyAll(),php,multithreading,process,Php,Multithreading,Process,我试图在PHP中测试一个竞争条件。我想让N个PHP进程准备好做一些事情,然后阻塞。当我说“开始”时,他们应该同时执行动作。希望这将证明这场比赛 在Java中,我将使用Object.wait()和Object.notifyAll()。我可以在PHP中使用什么 (Windows或linux本机答案都可以接受)PHP没有多线程。而且它也没有计划实施。 您可以尝试使用套接字进行黑客攻击,或者在多个进程之间进行通信 看 创建一个文件“wait.txt” 启动N个进程,每个进程的代码如下所示 删除“wai

我试图在PHP中测试一个竞争条件。我想让N个PHP进程准备好做一些事情,然后阻塞。当我说“开始”时,他们应该同时执行动作。希望这将证明这场比赛

在Java中,我将使用Object.wait()和Object.notifyAll()。我可以在PHP中使用什么


(Windows或linux本机答案都可以接受)

PHP没有多线程。而且它也没有计划实施。 您可以尝试使用套接字进行黑客攻击,或者在多个进程之间进行通信

  • 创建一个文件“
    wait.txt
  • 启动N个进程,每个进程的代码如下所示
  • 删除“
    wait.txt
    ”文件


通常使用PHP文件锁定方法。创建一个
RUN\u LOCK
或类似文件,并要求
文件存在(“RUN\u LOCK”)
。该系统还用于保护递归线程中潜在的无限循环

我决定要求执行该文件。另一种方法可能是,文件的存在调用阻塞算法。这取决于你的情况。总是更安全的情况应该更容易实现

等待代码:

/*prepare the program*/
   /* ... */
/*Block until its time to go*/
define("LOCK_FILE", "RUN_UNLOCK");    //I'd define this in some config.php
while(!file_exists(LOCK_FILE)) {
    usleep(1); //No sleep will eat lots of CPU
}
/*Execute the main code*/
   /* ... */
/*Delete the "run" file, so that no further executions should be allowed*/
usleep(1);  //Just for sure - we want other processes to start execution phase too
if(file_exists(LOCK_FILE))
    unlink(LOCK_FILE);
我想最好有一个阻塞函数,比如:

function wait_for_file($filename, $timeout = -1) {
    if($timeout>=0) {
        $start = microtime(true)*1000;    //Remember the start time
    }    
    while(!file_exists($filename)) {      //Check the file existence
        if($timeout>=0) {                 //Only calculate when timeout is set
           if((microtime(true)*1000-$start)>$timeout) //Compare current time with start time (current always will be > than start)
             return false;          //Return failure
        }   
        usleep(1);         //Save some CPU
    }
    return true;           //Return success
}
它实现了超时。你不需要它们,但也许其他人会需要。
用法:

这将输出:

Starting the blocking algorithm. Waiting for file: RUN_FOREST_RUN
Wait failed!

~or~

Starting the blocking algorithm. Waiting for file: RUN_FOREST_RUN
File found and deleted!

我会使用file,并检查
file\u是否存在
。在这里,它实际上与“同一时间”的含义无关。“同一时间”意味着平行,所有的开始都尽可能接近同一时刻。当你说“检查文件_是否存在”时,你是指旋转锁吗?这可能行得通。是的,有些功能。如果你用“usleep”,那就不会是一个问题。我已经写了你的评论作为答案,因为这是我迄今为止最好的答案。请随意写你自己的版本,我会删除我的版本以支持你。我喜欢你的答案,但当然我不会拒绝一些额外的荣誉:)谢谢。我认为将“usleep”添加到等待循环会导致线程的同步不那么紧密,所以我更喜欢没有它的版本。这个file_exists方法不雅观但很有效,很像PHP的其余部分;-)一微秒是很短的时间间隔。这些线程到底应该做什么?在我的例子中,它们应该参与一个相当标准的先读后写竞争条件,如所示的示例。对于设置测试用例,我们不关心在测试进程中烧掉一些CPU,而是关心让所有进程同时处于“运行”状态。在这里调用“usleep”会将进程标记为可中断的O/S,并且会分散代码的注意力,因此我认为在这里使用它是不正确的。当然,测试情况要大不相同-您可以牺牲一些CPU来获得精确的结果。对于其他用户,所需的同步级别可能更低。
header("Content-Type: text/plain; charset=utf-8"); 
ob_implicit_flush(true);while (@ob_end_clean());   //Flush buffers so the output will be live stream
define("LOCK_FILE","RUN_FOREST_RUN");  //Define lock file name again
echo "Starting the blocking algorithm. Waiting for file: ".LOCK_FILE."\n"; 
if(wait_for_file(LOCK_FILE, 10000)) {  //Wait for 10 secconds
    echo "File found and deleted!\n";
    if(file_exists(LOCK_FILE))   //May have been deleted by other proceses
        unlink(LOCK_FILE);
}
else {
    echo "Wait failed!\n";
}
Starting the blocking algorithm. Waiting for file: RUN_FOREST_RUN
Wait failed!

~or~

Starting the blocking algorithm. Waiting for file: RUN_FOREST_RUN
File found and deleted!