官术网_书友最值得收藏!

  • PHP Reactive Programming
  • Martin Sikora
  • 174字
  • 2021-07-09 19:06:18

The proc_open() and non-blocking fread()

Our goal is to have the means to start various subprocesses asynchronously. In this example, we'll use a simple PHP script that'll just sleep for a couple of seconds and represent our asynchronous task:

// sleep.php 
$name = $argv[1]; 
$time = intval($argv[2]); 
$elapsed = 0; 
 
while ($elapsed < $time) { 
    sleep(1); 
    $elapsed++; 
    printf("$name: $elapsed\n"); 
} 

This script takes two arguments. The first one is an identifier of our choice that we'll use to distinguish between multiple processes. The second one is the number of seconds this script will run while printing its name and the elapsed time every second. For example, we can run:

$ sleep.php proc1 3
proc1: 1
proc1: 2
proc1: 3

Now, we'll write another PHP script that uses proc_open() to spawn a subprocess. Also, as we said, we need the script to be non-blocking. This means that we need to be able to read output from the subprocess as it is printed using printf() above, while being able to spawn more subprocess, if needed:

// proc_01.php 
$proc = proc_open('php sleep.php proc1 3', [ 
    0 => ['pipe', 'r'], // stdin 
    1 => ['pipe', 'w'], // stdout 
    2 => ['file', '/dev/null', 'a'] // stderr 
], $pipes); 
 
stream_set_blocking($pipes[1], 0); 
 
while (proc_get_status($proc)['running']) { 
    usleep(100 * 1000); 
    $str = fread($pipes[1], 1024); 
    if ($str) { 
        printf($str); 
    } else { 
        printf("tickn"); 
    } 
} 
fclose($pipes[1]); 
proc_close($proc); 

We spawn a subprocess php sleep.php proc1 3 and then go into a loop. With a 100ms delay, we check whether there's any new output from the subprocess using fread(). If there is, we print it; otherwise, just write the word "tick". The loop will end when the subprocess terminates (that's the condition with the proc_get_status() function).

The most important thing in this example is calling the stream_set_blocking() function, which makes operations with this stream non-blocking.

主站蜘蛛池模板: 沂源县| 正阳县| 长寿区| 福建省| 平舆县| 资中县| 阳信县| 汤原县| 安福县| 永宁县| 英超| 治多县| 洛川县| 东阳市| 女性| 永福县| 遂昌县| 沂水县| 连江县| 达日县| 建水县| 东海县| 修武县| 杭州市| 九龙县| 营口市| 河津市| 安国市| 金塔县| 旺苍县| 灵宝市| 石楼县| 崇明县| 河北省| 临猗县| 东辽县| 彰化市| 延安市| 积石山| 建瓯市| 阿图什市|