Можем ли мы принудительно завершить выполнение программы на Си через долю секунды? - PullRequest
1 голос
/ 10 февраля 2012

Можем ли мы принудительно завершить выполнение программы на Си через доли секунды (диапазон миллисекунд) или из-за размера используемой памяти?Таким образом, я хочу ограничить печать содержимого в бесконечном цикле и ограничить переполнение буфера.

Я использую компилятор cygwin GCC4.3 и хочу реализовать его как инструмент в PHP, который принимает исходный код C каквведите и отобразите соответствующий вывод.

PS - 1. Я говорю миллисекунды, потому что мои проблемы с Си будут включать только очень простые арифметические вычисления.2. Чтобы ограничить время выполнения, set_time_limit () в php будет ограничивать все время выполнения PHP-скрипта, а не время, выделенное exec ()

Ответы [ 4 ]

2 голосов
/ 10 февраля 2012

Возможно, вы захотите выяснить, имеет ли ваша система nanosleep() из POSIX 2008. Обратите внимание, что даже если вы можете указать время в наносекундах, система может быть не в состоянии выдерживать тайм-ауты за миллисекундынадежно.

Возможно, вы обнаружите, что вместо него доступно µ-sleep() (пишется usleep()), хотя официально оно устарело.Указывает время, включая микросекунды.Быстрый поиск в Google по запросу «usleep windows» предлагает Sleep() в качестве альтернативы Windows.

См. Также: Сон меньше одной миллисекунды .

См. Также: Команда командной строки для автоматического уничтожения команды через определенное время .Программа, написанная там, в настоящее время не написана для работы с секундным хронометражем, но необходимые адаптации не будут очень трудными, если вы решите использовать субсекундный синхронизирующий интерфейс.

1 голос
/ 10 февраля 2012

Вы должны быть в состоянии использовать функцию будильника ().Хотя он находится в 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 */
}

update

Как указывает Джонатан, тревога (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-- и вставьте его в свой основной;

обновление 2

для ограничения памяти, попробуйте использовать setrlimit:

см. Установить размер стека с помощью setrlimit () и вызвать переполнение стека / segfault

для примера

0 голосов
/ 10 февраля 2012

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

Что касается требований ко времени, зачем просто жить с ограничением количества секунд и ограничивать выполнение до одной секунды?

0 голосов
/ 10 февраля 2012

Я делал нечто подобное в прошлом, и архитектура, которую я использовал, была - Пусть родительская 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 - это тестовый файл.

Это добавляет вам слой для компиляции и отладки, но это работает.

...