Название: Очистка очереди Отправлено: sergek от Май 27, 2015, 13:09 Коллеги, вопрос о том, как выполнить очистку очереди при нештатных ситуациях.
Многопользовательское приложение клиент/сервер. Сервер на Linux, работает в фоновом режиме (демон). Клиент подключается к серверу, отправляет запрос, дожидается ответа и отключается. Сервер при каждом подключении клиента порождает новый процесс (fork), который обслуживает своего клиента. Т.е. дочерних процессов столько, сколько клиентов подключились к серверу. Одновременно может исполняться только один запрос, поэтому на сервере организована очередь запросов, FIFO. Сейчас она сделана на основе таблицы в БД, но это не принципиально. Дочерний процесс заносит свой запрос в очередь и ожидает, когда его запрос в очереди не станет первым. Тогда он его исполняет, возвращает результат клиенту, удаляет свой запрос из очереди и завершается. Проблема возникает, если дочерний процесс по какой-либо причине при завершении не удалил свой запрос (например, аварийно завершился). В этом случае движение очереди останавливается и ни один запрос не будет исполнен. Остальные дочерние процессы подождут и по таймауту завершатся безрезультатно. Как защититься от такой ситуации? Пока вижу два варианта: - в главном процессе сервера при обработке сигнала SIGCHLD дочерних процессов проверять очередь, а если запрос завершившегося процесса еще там, удалять. Примерно так: Код: while((pid = waitpid(-1, &status, WNOHANG|WUNTRACED)) > 0) Есть еще какие-нибудь варианты? Или в консерватории нужно что-то поправить? :) Название: Re: Очистка очереди Отправлено: sergek от Май 28, 2015, 14:25 Сейчас она сделана на основе таблицы в БД, но это не принципиально. Вот тут я ошибался. В главном (родительском) процессе работать с БД (а у меня PostgreSQL) нельзя. Потому как если в момент, когда база открыта, производится вызов fork, то результат непредсказуем. У меня программа иногда зависала. Название: Re: Очистка очереди Отправлено: Akon от Май 29, 2015, 12:12 Должна быть симметрия. Если вы создаете данные в родительском процессе, то в нем же и удаляйте мусор. Операционная система тоже частенько подчищает за нами :)
Название: Re: Очистка очереди Отправлено: sergek от Май 29, 2015, 12:25 Данные создаются в дочернем процессе (при подсоединении клиента ему выделяется процесс, в котором запрос и ставится в очередь). А чистить должен родительский, т.к. он единственный, который работает все время (типа postmaster).
Я пока сделал так: при завершении любого дочернего процесса форкается вспомогательный "чистильщик", который и убирает мусор за этим завершившимся процессом. Как-то не здорово.. Наверное, я что-то намудрил. |