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

  • 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.

主站蜘蛛池模板: 福贡县| 贵州省| 察哈| 宁夏| 洮南市| 萝北县| 视频| 丰宁| 广水市| 荥阳市| 泰宁县| 武定县| 阜南县| 泽库县| 崇仁县| 高雄县| 柘城县| 新疆| 霞浦县| 承德市| 淮北市| 武安市| 内乡县| 桓台县| 绵竹市| 阿城市| 偏关县| 井冈山市| 赤壁市| 合川市| 锦州市| 玉山县| 茌平县| 韶山市| 德阳市| 沿河| 昭苏县| 阳曲县| 民和| 汝南县| 抚顺县|