Помогите понять функцию proc_open

proWoke

Новичок
Вот такой вот пример функции:
PHP:
<?
Header("Content-type: text/plain");

$spec = array (
	0 => array("pipe", "r"),
	1 => array("pipe", "w"),
	2 => array("file", "/tmp/error-output.txt", "a")
);

$proc = proc_open("cat",$spec,$pipes);

for ($i=0; $i<100; $i++)
 fwrite($pipes[0], "Hello World #$i\n");
fclose($pipes[0]);
while (!feof($pipes[1])) echo fgets($pipes[1], 1024);
fclose($pipes[1]);
proc_close($proc);
Вот как она работает я не могу понять. Я не понимаю связи между переменными функции. Т.е. причём тут команда "cat" из unix, которая выводит содержимое файла в консоль. Не могу понять каким образом создаётся файл в /tmp. Не понимаю, что значит "pipe" и на что вообще он влияет. Я понимаю, что данный скрипт сохраняет где то в буфере 100 hello word $i а потом считывает и выводит в браузер.
 

movRAX

Новичок
По сути, этот скрипт равносилен команде:
$ echo 'hello world' | cat
Энди Гутманс, PHP5 профессиональное программирование, стр.286
 

флоппик

promotor fidei
Команда форума
Партнер клуба
movRAX, спасибо, Кэп!

proWoke, твоя ошибка в том, что ты считаешь, что
команда "cat" из unix, выводит содержимое файла в консоль.
Возможно, стоит все же разобраться, как работает терминал и потоки в нем.
 

phprus

Moderator
Команда форума
proWoke
Недоговаривают (упрощают).
С точки зрения программы ничего нет. Нет ни консоли, ни экрана, совсем ничего.
Есть файловые дискрипторы через которые программа общается с так называемыми файлами(тут вспоминаем философию UNIX - все есть файл). Так вот в стародавние времена умные люди решили, что первые 3 дискриптора будут не простыми, а специальными и нарекли их стандартными потоками ввода-вывода. Имена им:
0 - стандартный ввод stdin
1 - стандартный вывод stdout
2 - стандартный поток ошибок stderr

Но этого им показалось мало и решили они дать возможность перенаправлять эти потоки в другие потоки...
Таким образом cat читая свой стандартный ввод и записывая его в свой стандартный вывод читает то, что ты направляешь ему на ввод, а читает твоя программа из потока, который привязан к stdout программы cat. (По умолчанию при запуске из терминала стандартные потоки привязываются к терминалу.)

P.S> Кстати такой пример, как у тебя - потенциальный deadlock, так как если записывая на стандартный ввод ты заполнишь буфер этого потока, то твоя программа заснет ожидая его освобождения для дозаписи оставшихся данных, а cat заполнив буфер вывода заснет ожидая освобождения буфера потока вывода, но он никогда не освободится, так как твоя программа никогда не дойдет до кода, читающего из него.
 
Сверху