лучший способ написать демон Linux [закрыто]

StackOverflow https://stackoverflow.com/questions/1210623

  •  06-07-2019
  •  | 
  •  

Вопрос

Для работы мне нужно написать демон TCP, который будет отвечать на наше клиентское программное обеспечение, и мне было интересно, есть ли у кого-нибудь какие-нибудь советы, как лучше всего это сделать.

Должен ли я разветвляться для каждого нового соединения, как обычно, я бы использовал потоки?

Это было полезно?

Решение

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

Вот несколько общих рекомендаций:

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

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

Другие советы

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

Только что искал и нашел этот SO-ответ: Какова цель раскошелиться? . Вы, очевидно, знаете ответ на этот вопрос, но ответ № 1 в этой теме имеет хорошие моменты о преимуществах fork ().

Помимо хорошего ответа @ hobodave, еще одно преимущество "разветвления на соединение" в том, что вы можете реализовать свой сервер очень просто, используя inetd или tcpserver или что-то подобное: вы можете использовать стандартный ввод и стандартный вывод для связи с сокетом, и don не нужно управлять прослушивающими сокетами (прослушивать соединения и т. д.) и т. д.

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

Самый простой и простой способ - написать демон на основе inetd; Ваше программное обеспечение может игнорировать тот факт, что оно работает по TCP-соединению, и просто обрабатывать ввод / вывод через stdin / stdout. Это хорошо работает в подавляющем большинстве случаев.

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

Загрузите исходный код OpenSSH. Они вложили много работы в разделение привилегий, это верно, это портативно, и это было тщательно изучено для обеспечения безопасности больше, чем что-либо еще.

Адаптируйте его под свои нужды, вы можете выбросить большую часть. Соблюдайте лицензионное соглашение конечно. Следите за будущими патчами с хорошим SCC.

Не беспокойтесь о производительности процессов разветвления и потоков, пока у вас не будет убедительных доказательств того, что это реальная проблема. Apache годами работал на самых загруженных сайтах, используя простую модель «процесс на клиент».

Если вы действительно амбициозны, вы можете использовать какую-то неблокирующую асинхронную модель ввода-вывода. Мне нравится Boost.Asio, но я увлекаюсь C ++.

Убедитесь, что ваш код правильно обрабатывает сигналы. HUP для перезагрузки конфигурации. СРОК, чтобы закрыть изящно.

Не пытайтесь написать свой собственный файл журнала. Используйте только системный журнал или просто пишите в stderr, который можно перенаправить в системный журнал. Это настоящая боль - пытаться настроить logrotate на домашних серверах, которые регистрируются немного по-разному.

Если вы хотите избежать многопоточности / разветвления, я бы рекомендовал использовать все неблокирующие операции ввода-вывода вместе с libevent . Libevent довольно хорошо известен как высокопроизводительное решение для событийного программирования.

Просмотрите ACE (C ++ / Java) . Он имеет ряд многопоточных, событийных и разветвленных TCP-реакторов, отвечающих вашим требованиям к связи. Вы также можете посмотреть Boost ASIO , который что-то делает аналогично

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top