6

I'm implementing a checking system in Ruby. It runs executables with different tests. If the solution is not correct, it can take forever for it to finish with certain hard tests. That's why I want to limit the execution time to 5 seconds.

I'm using system() function to run executables:

system("./solution");

.NET has a great WaitForExit() method, what about Ruby?.

Is there a way to limit external process' execution time to 5 seconds?

Thanks

Alex
  • 34,581
  • 26
  • 91
  • 135

2 Answers2

13

You can use the standard timeout library, like so:

require 'timeout'
Timeout::timeout(5) { system("./solution") }

This way you wont have to worry about synchronization errors.

shivam
  • 16,048
  • 3
  • 56
  • 71
Timon Vonk
  • 439
  • 3
  • 11
  • 1
    I chose this as accepted answer, because unlike EnabrenTane's solution, each test doesn't take 5 seconds minimum to complete. I use system("sudo killall solution") to kill the running process. – Alex Jan 01 '11 at 15:54
4

Fork your child which executes "./solution", sleep, check if its done, if not kill it. This should get you started.

pid = Process.fork{ system("./solution")}
sleep(5)
Process.kill("HUP", pid)

http://www.ruby-doc.org/core/classes/Process.html#M003153

EnabrenTane
  • 7,428
  • 2
  • 26
  • 44
  • Thanks for the link. I see I can use the fork method. But how can I connect it with system("./solution")? – Alex Jan 01 '11 at 12:54
  • Thank you so much! That's exactly what I need. There's just one problem. Now all tests take 5 seconds. However most of the tests are passed in less than a second. Is there any way to fix that? – Alex Jan 01 '11 at 13:32
  • It turned out that the processes were killed only "inside" Ruby. It went on to the next tests. However they were still in activity monitor eating all the CPU. – Alex Jan 01 '11 at 13:35