За последние 24 часа нас посетили 20794 программиста и 1716 роботов. Сейчас ищут 1422 программиста ...

Ограничение времени на выполнение внешней программы

Тема в разделе "PHP для профи", создана пользователем Skala, 18 сен 2017.

  1. Skala

    Skala Новичок

    С нами с:
    18 сен 2017
    Сообщения:
    12
    Симпатии:
    0
    У меня есть такая проблемма. На сервер отправляется *.pas файл, вкотором содержиться текст программы. Далее с помощью команды exec("fpc main.pas") компилирую файл в *.exe. Далее я запускаю этот exe файл( exec("start main.exe") ). Я сделал тестовою Pascal программу, выполнение которой превышает 0.5 сек.
    Что мне нужно сделать, чтобы сервер отправлял ответ о превышенном лимите времени, если это действительно случилось.
     
  2. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.584
    Симпатии:
    1.762
    Заглавие надо было сменить "ограничение времени выполнения внешней программы", а то я уже подумал, вроде форум по php, причём тут паскаль
     
  3. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.770
    Адрес:
    :сердА
    Готово.
     
  4. phpdev1

    phpdev1 Новичок

    С нами с:
    10 сен 2017
    Сообщения:
    22
    Симпатии:
    0
    В php запустить выполнение .pas файла в фоновом процессе, потом запустить цикл длительностью 0.5 сек, который каждые N ms будет проверять состояние фонового процесса.
    Если при проверке состояния оказывается, что процесс выполнен, прервать цикл и вернуть сообщение об успешном выполнении.
    Если цикл завершился самостоятельно, вернуть сообщение о таймауте.
     
  5. Skala

    Skala Новичок

    С нами с:
    18 сен 2017
    Сообщения:
    12
    Симпатии:
    0
    А можно пример кода?
     
  6. phpdev1

    phpdev1 Новичок

    С нами с:
    10 сен 2017
    Сообщения:
    22
    Симпатии:
    0
    PHP:
    1. <?php
    2.  
    3. // я на винде, поэтому для теста пингую несуществующий ip с задержкой 5 сек.
    4. $cmd = 'ping 192.168.0.255 -n 1 -w 5000 > nul';
    5. $process = proc_open($cmd, [], $pipes);
    6.  
    7. if(!is_resource($process)) {
    8.     exit('не получилось запустить процесс');
    9. }
    10.  
    11. $timeout = .5; // секунды
    12. $time_start = time();
    13.  
    14. while(time() < $time_start + $timeout) {
    15.     $status = proc_get_status($process);
    16.  
    17.     if(false === $status['running']) {
    18.         // процесс выполнился до таймаута
    19.         exit('ок');
    20.     }
    21.  
    22.     usleep(100000); // спать 100 мс, чтобы освободить процессор
    23. }
    24.  
    25. exit('таймаут');
     
    #6 phpdev1, 20 сен 2017
    Последнее редактирование: 20 сен 2017
  7. Skala

    Skala Новичок

    С нами с:
    18 сен 2017
    Сообщения:
    12
    Симпатии:
    0
    а как мне запустить *.exe файл
     
  8. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.584
    Симпатии:
    1.762
    А как бы ты запустил его из командной строки Windows ?
     
  9. Skala

    Skala Новичок

    С нами с:
    18 сен 2017
    Сообщения:
    12
    Симпатии:
    0
    start file.exe
     
  10. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.584
    Симпатии:
    1.762
    Ну также и тут сделай. Только file.exe с полным путём. Кстати, а start зачем?
     
  11. Skala

    Skala Новичок

    С нами с:
    18 сен 2017
    Сообщения:
    12
    Симпатии:
    0
    То есть вместо $cmd='ping 192.168.0.255 -n 1 -w 5000 > nul'; прописать $cmd='ping file.exe -n 1 -w 5000 > nul';
    --- Добавлено ---
    у меня file.exe находиться в той же директории что и скрипт
     
  12. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.584
    Симпатии:
    1.762
    Ну я не полагаюсь, на то что с запуском скрипта сменится текущая директория.
     
  13. phpdev1

    phpdev1 Новичок

    С нами с:
    10 сен 2017
    Сообщения:
    22
    Симпатии:
    0
    Решил файл пингануть? Правильно будет так:
    PHP:
    1. $cmd = './file.exe';
     
  14. Skala

    Skala Новичок

    С нами с:
    18 сен 2017
    Сообщения:
    12
    Симпатии:
    0
    не помогло
     
  15. Skala

    Skala Новичок

    С нами с:
    18 сен 2017
    Сообщения:
    12
    Симпатии:
    0
    все равно пишет ок, хотя файл выполняеться больше пол секунды
     

    Вложения:

    • index.txt
      Размер файла:
      626 байт
      Просмотров:
      3
  16. phpdev1

    phpdev1 Новичок

    С нами с:
    10 сен 2017
    Сообщения:
    22
    Симпатии:
    0
    Скорее всего твой файл запускается и сразу же падает по ошибке, поэтому при проверке статуса php видит, что процесс уже завершен.

    Я правильно понимаю, что выполнение main.pas создает main.exe? Что возваращает exec('main.pas')?
     
  17. Skala

    Skala Новичок

    С нами с:
    18 сен 2017
    Сообщения:
    12
    Симпатии:
    0
    У меня ошыбка. Вместо exec('main.pas') должно быть exec( "fpc main.pas" ). Эта команда создает main.exe. Но все равно не работает
     
  18. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.770
    Адрес:
    :сердА
    А теперь Главный Вопрос: Автор, что ты пытаешься сделать-то? И зачем тебе паскаль из пыхи дергать? Может быть, найдутся более правильные решения, если ты полностью сформулируешь задачу, а не то, как ты ее решаешь?
     
  19. Skala

    Skala Новичок

    С нами с:
    18 сен 2017
    Сообщения:
    12
    Симпатии:
    0
    Мне нужно чтобы пользователь отправлял на сервер решение задачи, а сервер проверял проходит ли задача по тестах
     
  20. phpdev1

    phpdev1 Новичок

    С нами с:
    10 сен 2017
    Сообщения:
    22
    Симпатии:
    0
    Тебе нужно понять, что возвращает твой процесс. Для этого немного поменяй вызов proc_open:
    PHP:
    1. $process = proc_open($cmd, [
    2.     0 => [ 'pipe', 'r' ],
    3.     1 => [ 'file', './stdout.log', 'a' ],
    4.     2 => [ 'file', './stderr.log', 'a' ],
    5. ], $pipes);
    В файлах stdout.log или stderr.log будет информация об ошибке.
     
  21. Skala

    Skala Новичок

    С нами с:
    18 сен 2017
    Сообщения:
    12
    Симпатии:
    0
    в файле stderr.log пишет:
    "." не является внутренней или внешней
    командой, исполняемой программой или пакетным файлом.
     
  22. phpdev1

    phpdev1 Новичок

    С нами с:
    10 сен 2017
    Сообщения:
    22
    Симпатии:
    0
    :)
    PHP:
    1. $cmd = dirname(__FILE__) . '/main.exe';
     
  23. Skala

    Skala Новичок

    С нами с:
    18 сен 2017
    Сообщения:
    12
    Симпатии:
    0
    Иногда пишет таймаут, а иногда ок хотя файл один и тот же
     
  24. phpdev1

    phpdev1 Новичок

    С нами с:
    10 сен 2017
    Сообщения:
    22
    Симпатии:
    0
    Значит иногда процесс успевает выполниться за 0.5 сек, а иногда нет.
     
  25. Skala

    Skala Новичок

    С нами с:
    18 сен 2017
    Сообщения:
    12
    Симпатии:
    0
    ОК. Спасибо за помощь