Подтвердить что ты не робот

Есть ли разница между socketpair и парой неназванных труб?

Я хотел бы знать не только различия на стороне пользователя, но и различия/общие части в реализации ядра Linux.

4b9b3361

Ответ 1

  • Трубы
  • являются однонаправленными, поэтому вам нужно иметь две трубы для двунаправленной связи, тогда как гнездовая пара двунаправлена.

  • трубы всегда ориентированы на поток, тогда как сокеты-пары могут быть ориентированы на датаграммы.

  • socketpairs являются нормальными AF_UNIX сокетами, что означает, что через них могут передаваться вспомогательные сообщения типа SCM_RIGHTS и SCM_CREDENTIALS.

В ядре каналы реализованы в коде файловой системы и сокетах в сетевом коде.

Ответ 2

Возможности сокета-парама shutdown() и SCM_RIGHTS необходимы для обеспечения устойчивой к расовой связи связи с подпроцессами в многопоточной программе.

Трубы могут быть продублированы случайно в случае нескольких потоков pipe() и fork() одновременно; в этом случае конец записи трубы никогда не может быть закрыт, и EOF никогда не может произойти на считываемом конце, что вызывает тупик. Даже для тех программ, которые используют fork() только для подпроцессов (т.е. Все fork() оперативно сопровождаются execve() в дочернем элементе), захват канала параллельным fork() еще продолжается с настройкой бита FD_CLOEXEC, запрет использования не переносимого системного вызова Linux pipe2(), который принимает O_CLOEXEC.

Решение этой угрозы переносимым образом, также для программ, которые fork() без вызова execve(), включает в себя socketpairs:

  • Для исходящего канала (т.е. записи из основной программы в подпроцесс): используйте сокет-пак вместо канала и вызовите shutdown() до close() от родителя, чтобы вызвать условие безопасности EOF, независимо от того, был дублирован файловый дескриптор.
  • Для входящего канала (т.е. чтения из подпроцесса) создайте канал в дочернем элементе (так, чтобы конец записи никогда не был виден в родительском объекте для случайного дублирования) и отправлял только конец чтения родительскому элементу через сокет с a SCM_RIGHTS.