Можем ли мы принудительно завершить выполнение программы C через долю секунды (диапазон миллисекунд) или размер используемой памяти? Таким образом, я хочу ограничить печать содержимого в бесконечном цикле и ограничить переполнение буфера.
Я использую компилятор cygwin GCC4.3 и хочу реализовать его как инструмент в PHP, который принимает исходный код C как входной сигнал и отображает соответствующий вывод.
PS – 1. Я говорю миллисекунды, потому что мои проблемы C будут включать только очень простые арифметические вычисления. 2. Чтобы ограничить время выполнения, set_time_limit () в php ограничил бы время выполнения всего PHP-скрипта, а не время, отведенное exec ()
Вы должны иметь возможность использовать функцию alarm (). Хотя он найден в unistd.h, он является функцией POSIX.1-2001 и должен быть доступен под cygwin. Если SIGALRM не обрабатывается, он убивает процесс.
Попробуй:
#include <stdio.h> #include <unistd.h> int main() { alarm(5); /* raise alarm after 5 seconds */ while(1) { printf("Running forever\n"); } return 0; /* never reached */ }
Как указывает jonathan, аварийный сигнал (2) работает только в секундах, поэтому вместо него можно использовать setitimer (также совместимый с POSIX)
#include <stdio.h> #include <sys/time.h> int main() { /* --CUT HERE-- */ struct itimerval timer; timer.it_value.tv_sec = 0; timer.it_value.tv_usec = 5000; /* 5 milliseconds */ timer.it_interval.tv_sec = 0; timer.it_interval.tv_usec = 0; setitimer(ITIMER_REAL, &timer, NULL); /* --END CUT-- */ while(1) { printf("Running forever\n"); } return 0; /* never reached */ }
если вышеуказанное работает в вашей системе, скопируйте код с –CUT HERE– в –END CUT – и вставьте его в свою основную;
для ограничения памяти попробуйте использовать setrlimit:
см. « Установить размер стека с помощью setrlimit () и спровоцировать переполнение стека / segfault
для примера
Возможно, вам захочется выяснить, имеет ли ваша система nanosleep()
от POSIX 2008. Обратите внимание, что даже если вы можете указать время в наносекундах, система, возможно, не сможет надежно nanosleep()
тайминги.
Вы можете обнаружить, что µ-sleep()
(spelled usleep()
) доступен вместо этого, хотя он официально устарел. Он определяет время, включая микросекунды. Быстрый поиск в Google для «usleep windows» предлагает Sleep()
как родную альтернативу Windows.
См. Также: Сон менее одной миллисекунды .
См. Также: Командная строка для автоматического уничтожения команды через определенное время . В настоящее время программа не написана для работы с субсекундной синхронизацией, но необходимые адаптации не будут очень сложными, если вы решите использовать вспомогательный временной интерфейс.
Чтобы ограничить размер памяти, просто не используйте динамическое распределение памяти или рекурсию. Затем вы можете гарантировать, что требования к памяти ограничены (это стандарт кодирования для критически важных систем безопасности).
Что касается временных требований, зачем просто жить с ограничением секундной гранальности и ограничить исполнение на одну секунду?
Я сделал что-то подобное в прошлом, и архитектура, которую я использовал, – это иметь родительскую C-программу, например, main.c, код, аналогичный приведенному ниже (обратите внимание, что это не производственный код и даже не дает возможности скомпилировать код ниже только для демонстрации).
// ---------------------- main.c ---------------- int main_child(); // the body is defined in "your_test_source.c" int main() { pthread_t tid; // create child thread pthread_create(tid, NULL, main_child, NULL); // start monitoring the child thread // ... // you can kill child thread by calling pthread_exit // and check for memory usage by system calls. return 0; } #define main main_child // we change the main function to main_child #include "your_test_source.c" #undef main // ---------------------- end -------------
your_test_source.c – это тестовый файл.
Это добавляет слой для компиляции и отладки, но он работает.