Взаимодействие с демоном в C ++ с сокетами - PullRequest
3 голосов
/ 24 января 2011

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

Я использую упаковщики сокетов, предоставленные на http://linuxgazette.net/issue74/tougher.html

Спасибо за любую помощь

Ответы [ 5 ]

3 голосов
/ 24 января 2011

Вам нужно будет использовать потоки, чтобы сделать операции сокетов асинхронными.Или используйте какую-нибудь библиотеку, которая уже реализовала это, одна из лучших - Boost Asio .

2 голосов
/ 24 января 2011

Обычно демоны используют циклы событий, чтобы избежать проблемы ожидания событий.

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

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

  • libevent.
  • цикл событий glib.
  • libev.
  • boost :: asio
  • ...
2 голосов
/ 24 января 2011

Есть несколько способов справиться с этой проблемой.Это наиболее распространенное использование цикла событий и что-то вроде libevent .Затем вы используете неблокирующие сокеты.

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

1 голос
/ 24 января 2011

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

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

Ссылка на LinuxGazette - это базовое введение в сетевое программирование. Если вы хотите немного глубже, взгляните на Руководство Beej по сетевому программированию , где различные доступные вызовы API объяснены в нескольких деталях ... и, возможно, заставят вас ценить больше обертки библиотеки, такие как Boost :: ASIO.

0 голосов
/ 24 января 2011

Может быть стоит сохранить контроль над циклом событий самостоятельно - он не сложен и обеспечивает гибкость в будущем.

"Псевдокод C ++" для цикла событий.

while (!done)
    {
        bool workDone = false;
        // Loop over each event source or internal worker
        for each module
        {
            // If it has work to do, do some.
            if (module.hasWorkDoTo())
            {
                // Generally, do as little work as possible; e.g. process a single event for this module.
                // But tinker with this to manage priorities if need be.
                // E.g. Maybe allow the GUI to flush its queue.
                module.doSomeWork();
                workDone = true;
            }
        }
        if (!workDone)
        {
            // System idle. No Sleep for a bit so we have benign idle baheviour.
            nanosleep(...);
        }
    }
...