2

I'm trying to make an online judge written PHP. My code currently looks like:

exec("gcc /var/www/qwerty.c -o /var/www/binary",$output,$returnval);
print_r($output);
exec("cat /var/www/qwe.txt | /var/www/binary",$output,$returnval);
print_r($output);

However, I want each process spawned by exec to have at most 1 second to run. I'm not sure how to do this. set_time_limit() isn't working

Rofael Behnam
  • 39
  • 1
  • 4
  • Witness, if you will, my improvement to the question title. – Lightness Races in Orbit Feb 03 '12 at 12:52
  • @ManseUK: Read that very page: `The set_time_limit() function and the configuration directive max_execution_time only affect the execution time of the script itself. Any time spent on activity that happens outside the execution of the script such as system calls using system(), stream operations, database queries, etc. is not included when determining the maximum time that the script has been running. This is not true on Windows where the measured time is real. ` – Lightness Races in Orbit Feb 03 '12 at 12:54
  • I've edited your post to make what I think you want clearer. The question now is, what do you want to happen if the process takes more than 1 second? – Adam Wright Feb 03 '12 at 12:55
  • @LightnessRacesinOrbit comment removed !!!! ta – Manse Feb 03 '12 at 12:55
  • Closers: No, no, no. This is a real question. It might have been badly phrased originally, but I think with an edit or two and a comment, the real issue can easily be brought out. – Adam Wright Feb 03 '12 at 13:00
  • @AdamWright: If nothing else, it's an obvious dup of a lot of previous questions (e.g. http://stackoverflow.com/questions/2603912/php-set-timeout-for-script-with-system-call-set-time-limit-not-working, more or less), and it shows absolutely no prior research. The fact is, it may be a real problem for the OP, but this is not a real _question_ for Stack Overflow. – Lightness Races in Orbit Feb 03 '12 at 13:04
  • @LightnessRacesinOrbit Last comment by me (as this is meta discussion), but if you think it's a dupe, close a dupe. Not as "Not a real question". – Adam Wright Feb 03 '12 at 13:09

3 Answers3

8

I would use the proc_ functions as suggested by @Adam Wright, but a quick alternative to Linux-like environments is to use the GNU timeout command before your command:

// If it took more than 1 second, $returnval will got the exit code 124
exec('timeout 1 gcc /var/www/qwerty.c -o /var/www/binary', $output, $returnval);
Paulo Freitas
  • 13,194
  • 14
  • 74
  • 96
5

You can probably use ulimit for that:

exec(" ( ulimit -t 1 ; gcc ... | /var/www/binary) ");

That of course only works if the process uses active CPU time, not if it waits for I/O endlessly.

mario
  • 144,265
  • 20
  • 237
  • 291
3

This can be achieved using the proc_ family of functions. Launch your processes using proc_open. Repeatedly poll using proc_status (with some small sleep in-between polls) until either the process has returned or 1 second has passed. If 1 second passes without proc_status indicating the process has finished, use proc_terminate (or proc_close) to kill it off, and take appropriate action.

I'm not saying that spawning external processes in a PHP script is a good idea, though.

Adam Wright
  • 48,938
  • 12
  • 131
  • 152