Вопросы, связанные с оформлением процесса - PullRequest
0 голосов
/ 11 января 2012

Я делаю сервер и использую fork () для создания дочерних процессов, но у меня есть сомнения по этому поводу.Вот некоторые из них:

  1. Зачем вам нужно закрывать основной сокет в дочернем процессе и новый принятый соединением сокет в родительском процессе?(после принятия нового соединения) я подумал, что сокеты - это только целые числа с некоторым идентификатором, которые используются для доступа к открытым сокетам в каком-то общесистемном объекте, который приемлем только через вызовы системных функций.В этом случае fork будет копировать только целое число, но не будет влиять на открытый сокет.
  2. Я проверил и обнаружил, что если я разветвляю процесс внутри метода класса, все члены копируются.Ну, я обнаружил, что это копирование при редактировании, значит ли это, что мой класс сервера будет копироваться в каждом дочернем элементе, который использует непостоянную функцию?Как сделать так, чтобы память распределялась между всеми такими процессами (например, список задач, и каждый дочерний элемент что-то вкладывает в него, пока родитель читает из него материал)?Я думаю, что fork не подходит для этого.Какой самый лучший способ?

PS Я почти уверен, что знаю ответ на второй вопрос, который является clone (), но просто хотел убедиться, что это правильная функция.

Ответы [ 4 ]

1 голос
/ 11 января 2012
  1. int является дескриптором, но сам сокет все еще связан с процессом. Ребенок закрывает сокет прослушивания в основном по соображениям безопасности (ему это не нужно, и если ребенок когда-либо порождает другой процесс, этот процесс также унаследует сокет); серверный процесс закрывает сокет нового соединения, потому что в противном случае соединение будет оставаться открытым до тех пор, пока не завершится серверный процесс (сокет существует до тех пор, пока хотя бы один процесс все еще имеет дескриптор).

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

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

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

Наконец, существует третий вариант: цикл обработки событий, отслеживающий несколько сокетов, уделяя внимание каждому, только если что-то действительно происходит. Посмотрите документацию по функциям select и poll.

1 голос
/ 11 января 2012
  1. Сокеты в Unix являются дескрипторами файлов, и они действительно являются целыми числами, как видит пользователь, но на самом деле они являются индексами в таблице, которую ядро ​​поддерживает для каждого процесса.В этой таблице каждый дескриптор файла (FD) ссылается на описание открытого файла (OFD), которые являются общесистемными объектами, поддерживаемыми в ядре.Когда вы делаете fork(), открытые файловые дескрипторы дублируются, и как дочерний элемент, так и родительский элемент указывают на одно и то же OFD.Наличие двух FD, которые ссылаются на один и тот же OFD, обычно не является проблемой, но особенно с сокетами у них могут быть тонкие проблемы, поскольку соединение закрывается, только когда вы закрываете все FD, которые ссылаются на него.*

  2. Вам действительно следует подумать об использовании потоков (не закрывайте сокеты, если вы используете потоки!).clone является системным вызовом linux и не предназначен для непосредственного использования.Ваша альтернатива - использовать разделяемую память, но она более сложная.

0 голосов
/ 11 января 2012

Я думаю, что вы, возможно, захотите просмотреть эту книгу как ссылку на fork ().

  1. Да, вам нужно закрыть сокет, связанный с прослушиванием в дочернем элементеи принял сокет в родительском.Целочисленные ака файловые дескрипторы указывают на реальные структуры , смотрите это , поэтому, если вы не хотите, чтобы ядро ​​дампировало новое соединение на дочернем или родительском объекте, способном отправлять данные на подключенный клиент, вы можете предотвратить это напрямую.
  2. Для обмена данными между процессами лучше всего использовать разделяемую память.Книга, на которую я ссылался, также содержит немало информации об этом.В общем, если вам нужно совместно использовать память без разделяемой памяти, вы можете захотеть взглянуть на потоки.

PS Я не уверен, какой метод clone () вы имеете в виду.Копирование объекта осуществляется с помощью конструкторов копирования.

0 голосов
/ 11 января 2012

Формирование дубликатов файловых дескрипторов, поэтому вы должны закрыть дубликат.

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

Возможно, вы намеревались создать новый поток чем разветвление нового процесса ?

...