Являются ли соединения труб легкими?

В приложении linux я использую каналы для передачи информации между потоками.

Идея использования труб заключается в том, что я могу подождать сразу несколько каналов, используя опрос (2). Это хорошо работает на практике, и мои потоки спать большую часть времени. Они только просыпаются, если есть что-то делать.

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

Btw: В моем приложении я только время от времени отправляю одиночные байты. Подумайте о моих трубах как о простых очередях сообщений, которые позволяют мне получать входящие потоки, сообщать им о передаче некоторых статусных данных или завершать.

Ответ 1

Когда вы используете Linux, вы можете исследовать и сравнить производительность pipe с eventfd. Они технически быстрее и легче, но вам будет очень повезло, чтобы на самом деле увидеть выигрыш на практике.

http://www.kernel.org/doc/man-pages/online/pages/man2/eventfd.2.html

Ответ 2

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

Отправка байта по каналу потребует минимум 3 системных вызовов (запись, опрос, чтение). Использование операций очереди в очереди и операций pthread (mutex_lock, cond_signal) требует гораздо меньших накладных расходов. Открытые дескрипторы файлов определенно потребляют ресурсы ядра; почему процессы обычно ограничены 256 открытыми файлами по умолчанию (не то, что ограничение не может быть расширено, когда это необходимо).

Тем не менее, решение pipe/poll для межпоточной связи также имеет свои преимущества: особенно, если вам нужно ждать ввода из комбинации источников (сеть + другие потоки).

Ответ 3

Измерьте и вы узнаете. Полные процессы с трубами достаточно легки для большого количества приложений. Другие приложения требуют чего-то более легкого веса, например, потоки ОС (pthreads - популярный выбор для многих приложений Unix) или сверхлегкий вес, например, потоковый пакет пользовательского уровня, который никогда не переходит в режим ядра, кроме как для обработки ввода-вывода. Хотя единственный способ знать наверняка - это измерить, трубы, вероятно, достаточно хороши для нескольких десятков потоков, тогда как, вероятно, вам понадобятся потоки уровня пользователя, когда вы получите несколько десятков тысяч потоков. Именно там, где границы должны быть составлены с использованием сегодняшних кодов, я не знаю. Если бы я хотел знать, я бы измерил: -)

Ответ 4

Вы также можете использовать socketpair, который более переносимый, чем eventfd, потому что он POSIX.