Почему я должен закрыть fds при чтении и записи в канал?

Из кода в документации PHP: Операторы массивов :

 "apple", "b" => "banana");
$b = array("a" => "pear", "b" => "strawberry", "c" => "cherry");

$c = $a + $b; // Union of $a and $b
echo "Union of \$a and \$b: \n";
var_dump($c);

$c = $b + $a; // Union of $b and $a
echo "Union of \$b and \$a: \n";
var_dump($c);
?>

При выполнении этот скрипт выведет следующее:

Union of $a and $b:
array(3) {
  ["a"]=>
  string(5) "apple"
  ["b"]=>
  string(6) "banana"
  ["c"]=>
  string(6) "cherry"
}
Union of $b and $a:
array(3) {
  ["a"]=>
  string(4) "pear"
  ["b"]=>
  string(10) "strawberry"
  ["c"]=>
  string(6) "cherry"
}

10
задан GEOCHET 10 June 2009 в 15:07
поделиться

4 ответа

Ваш канал представляет собой однонаправленный поток - с файловым дескриптором на каждом конце. Нет необходимости close () на любом конце канала, чтобы данные могли проходить по нему.

если ваш канал охватывает процессы (т.е. создается до fork (), а затем родитель и потомок используют его для общаться) у вас может быть один конец записи и один конец чтения. Тогда рекомендуется закрыть ненужные концы трубы. Это

  • гарантирует, что, когда конец записи закроет канал, это будет видно со стороны чтения. В качестве примера предположим, что ребенок пишет сторону, и он умирает. Если родительская сторона записи не была закрыта, то родительский элемент не получит "eof" (чтение нулевой длины ()) из канала - потому что канал имеет открытый конец записи.
  • проясните, какой процесс выполняет запись и какой процесс выполняет чтение на конвейере.

, если ваша труба охватывает резьбу (в рамках одного процесса), не закрывайте нежелательные концы трубы. Это связано с тем, что дескриптор файла удерживается процессом, и закрытие его для одного потока закроет его для всех потоков, и, следовательно, канал станет непригодным для использования.

Ничто не мешает вам иметь один процесс, непрерывно записывающий в канал и другой процесс чтения. Если у вас возникла эта проблема, сообщите нам более подробную информацию, чтобы помочь вам.

Ничего не мешает, если один процесс непрерывно пишет в конвейер, а другой - читает. Если у вас возникла эта проблема, сообщите нам более подробную информацию, чтобы помочь вам.

Ничего не мешает, если один процесс непрерывно пишет в конвейер, а другой - читает. Если у вас возникла эта проблема, сообщите нам более подробную информацию, чтобы помочь вам.

25
ответ дан 3 December 2019 в 14:11
поделиться

После выполнения вилки все fd-файлы дублируются. В каждом процессе оба конца трубы открыты. Если вы хотите использовать только один конец, вы должны закрыть другой (если ваш процесс пишет, закройте конец чтения).

Помимо очевидного факта, что если вы не закроете дескрипторы, ОС сохранит дополнительные записи в открытом файле table, если вы не закроете конец записи канала, считыватель никогда не получит EOF, так как все еще есть способ ввода данных в канал. AFAIK (и IIRC) нет проблем в том, чтобы не закрыть читаемый fd в другом процессе, то есть кроме того, что файл открыт без причины.

Это также рекомендуется (как хорошая практика, а не то, что это тоже влияет много), что вы закрываете все дескрипторы перед выходом из приложения (то есть

11
ответ дан 3 December 2019 в 14:11
поделиться

Канал не дает вам ни двунаправленного канала, ни многоадресной рассылки. Канал имеет только два конца, у него нет одного конца записи и нескольких концов чтения.

Если вам нужно много читателей, вам нужно столько каналов, сколько у вас есть процесса чтения.

0
ответ дан 3 December 2019 в 14:11
поделиться

«Похоже, что приведенный выше пример работает только для одной записи и одного чтения»

Это потому, что после одного чтения и записи ваш код завершается. Вам нужно продолжать писать в цикле и читать в цикле, чтобы добиться непрерывности. Похоже, это не имеет ничего общего с закрытием FD. Как упоминалось в предыдущем ответе, вам нужен один конец каждого процесса, чтобы другой был закрыт.

Надеюсь, я правильно понимаю запрос.

0
ответ дан 3 December 2019 в 14:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: