[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Limiting the CPU time of program started via SYSTEM

Garance A Drosehn

6/15/2005 2:19:00 AM

Let's say I have a ruby script which calls system() to run some
arbitrary program. Since that program might spiral off into some evil
infinite-loop, is there some way for me to say "execute this, but for
no longer than 2 seconds of CPU time"? In the C-world I might use
something like setrlimit, but I'm not sure how easy that would be to
do from within a ruby script.

Note that I don't want to limit the CPU time of the script itself. I
just want to limit the CPU time for specific applications that I
execute via system().

--
Garance Alistair Drosehn = drosihn@gmail.com
Senior Systems Programmer or gad@FreeBSD.org
Rensselaer Polytechnic Institute; Troy, NY; USA


5 Answers

Ara.T.Howard

6/15/2005 3:41:00 AM

0

Gary Wright

6/15/2005 3:48:00 AM

0


On Jun 14, 2005, at 10:19 PM, Garance A Drosehn wrote:
> Let's say I have a ruby script which calls system() to run some
> arbitrary program. Since that program might spiral off into some evil
> infinite-loop, is there some way for me to say "execute this, but for
> no longer than 2 seconds of CPU time"? In the C-world I might use
> something like setrlimit, but I'm not sure how easy that would be to
> do from within a ruby script.

I'm going to give a general Unix programming answer and then some
comments about doing it in Ruby.

The basic technique is to fork a child process, have the child
process use setrlimit() to establish the resource limitations and
then have the child fork *again*. The "grandchild" process then
does the actual work subject to the limitations set by the child
process. The child process can exit once the grandchild has started.
This works because resource limits are inherited across a fork.

A quick and dirty way to accomplish all this in Ruby:

system(%q{
echo $$; # show the current pid
ulimit -a; # show the current limits
ulimit -t 1; # change the CPU time limit to 1 sec
sh -c 'echo $$; ulimit -a' # start a new process and show limits
})

Note, you can't use this technique to change the limits of the
current process because system does its thing in a child process, not
in the process that called system.

If you wanted to do all this within Ruby (i.e. without using system)
you are stuck because the standard Process class doesn't support
setrlimit (and the related getrlimit). Google has a link to an
RAA project that no longer exists at RAA called 'resource' that
looks like it implemented these functions. Maybe someone else is
aware of a similar project. If you had setrlimit you could do
something like:

puts "main: #{Process.pid}"
unless child_pid = fork
puts "child: #{Process.pid}"
# setrlimit(....)
unless grand_child = fork
puts "grandchild: #{Process.pid}"
puts "grandchild: doing the work"
exit(0)
end
puts "grandchild: exited: #{Process.wait}"
exit(0)
end
puts "child: exited: #{Process.wait}"



Tanaka Akira

6/15/2005 3:56:00 AM

0

In article <97880ae0506141918e56d386@mail.gmail.com>,
Garance A Drosehn <drosihn@gmail.com> writes:

> Let's say I have a ruby script which calls system() to run some
> arbitrary program. Since that program might spiral off into some evil
> infinite-loop, is there some way for me to say "execute this, but for
> no longer than 2 seconds of CPU time"? In the C-world I might use
> something like setrlimit, but I'm not sure how easy that would be to
> do from within a ruby script.
>
> Note that I don't want to limit the CPU time of the script itself. I
> just want to limit the CPU time for specific applications that I
> execute via system().

Ruby 1.9 has Process.setrlimit (and Process.getrlimit).

% ruby -e 'Process.wait fork { Process.setrlimit Process::RLIMIT_CPU, 2, 2; exec "yes > /dev/null" }'
--
Tanaka Akira


Nakada, Nobuyoshi

6/15/2005 4:02:00 AM

0

Hi,

At Wed, 15 Jun 2005 12:40:47 +0900,
Ara.T.Howard wrote in [ruby-talk:145444]:
> > Let's say I have a ruby script which calls system() to run some
> > arbitrary program. Since that program might spiral off into some evil
> > infinite-loop, is there some way for me to say "execute this, but for
> > no longer than 2 seconds of CPU time"? In the C-world I might use
> > something like setrlimit, but I'm not sure how easy that would be to
> > do from within a ruby script.

Resouce module is in "rough".
<http://www.ruby-lang.org/cgi-bin/cvsweb.cgi/rough/ext/res...

> maybe something like
>
> harp:~ > cat a.rb
> require 'timeout'
> def spawn cmd, sec
> pid = fork{ system cmd }
> begin
> Timeout::timeout(sec){ Process::waitpid2(pid).last }
> rescue Timeout::Error => e
> Process::kill 'TERM', pid rescue nil

You should give a chance to terminate gently to the child process, I
guess.

> Process::kill 'KILL', pid rescue nil

--
Nobu Nakada


Ara.T.Howard

6/15/2005 4:29:00 AM

0