#c #linux #unix #gcc #posix
#c #linux #unix #gcc #posix
Вопрос:
Я пишу программу (реализацию генетического алгоритма), которая выполняет другую программу, используя «системный» метод для вычисления пригодности. Проблема в том, что другая программа иногда зависает на неограниченное количество времени. Как я могу выполнить программу с некоторым ограничением по времени из C .
Приветствуются решения как на POSIX, так и на c . И более или менее это приложение будет запущено один раз, поэтому решение не обязательно должно быть очень элегантным.
Я запускаю дистрибутив Linux CentOS и тестирую на Cygwin. Для компилятора я использую gcc 4.1.2 с библиотекой boost.
Любая помощь приветствуется
Ответ №1:
Вместо system
выполните программу с помощью идиомы fork
/ exec
. Перед exec
, установите RLIMIT_CPU
максимальное значение с setrlimit
в дочернем элементе.
Убедитесь, что дочерний элемент не игнорирует SIGXCPU
(что очень маловероятно).
Комментарии:
1. Можете ли вы подробнее объяснить, как убедиться, что SIGXCPU не игнорируется?
2. @Sergej: большинство сигналов по умолчанию приводят к завершению работы программы, но программист может решить перехватить или проигнорировать сигнал явно с помощью
sigaction
. Я никогда не видел ни одной программы, которая перехватывала бы или игнорировалаSIGXCPU
, и я не уверен, возможно ли это, но разумно запустить программу и выполнитьkill -XCPU
команду над ней на всякий случай.3. Это измеряет время процессора, но, согласно моему пониманию вопроса, Sergej ищет ограничение на время работы настенных часов.
4. @Ben: вы правы, это работает, если программа продолжает использовать процессорное время без необходимости. Если она зависает в ожидании, решение Errata лучше.
5. Моя вторая программа зависает. Она использует процессор, но никогда не даст никакого результата и, следовательно, должна быть отключена через некоторое время. Что происходит (исходя из моих субъективных оценок), так это то, что в presolver из библиотеки GLPK, используемой в этой второй программе, есть ошибка, и иногда он может входить в бесконечный цикл. Итак, каков наилучший подход в этой ситуации?
Ответ №2:
Вы могли бы создать таймер (например, с помощью boost timer), а затем попытаться убить дочерний процесс … это предполагает, что вы используете fork и exec для запуска всех своих дочерних процессов, и вы сохранили каждый pid.
Ответ №3:
-
Если эта «другая» программа ваша или у вас есть исходные тексты по общедоступной лицензии, вероятно, лучше сделать ее не отдельной программой, а отдельным потоком в основной программе. В этом случае вы можете легко управлять этим.
-
Если эта «другая» программа ваша или у вас есть исходные тексты по общедоступной лицензии, но вы не хотите (или не можете) следовать приведенному выше предложению, возможно, проще исправить программу, чтобы предотвратить зависание.
-
Дерьмовый метод:
- выполните fork(), запомните PID, вызовите exec *(«my-prog», …)
- создайте поток в основной программе с таймером.
- при срабатывании time завершите процесс с помощью kill() и запомните PID.
Комментарии:
1. Другие процессы могут быть остановлены, но завершение потока оставляет весь процесс в несогласованном состоянии.