Force a program to stop if runtime exceeds given duration

  • Thread starter Aldric Giacomoni
  • Start date
A

Aldric Giacomoni

Any idea how to do that?
Say, I don't want a program to run longer than 5 hours.. How would that
be implemented?

--Aldric
 
G

Glen Holcomb

[Note: parts of this message were removed to make it a legal post.]

Any idea how to do that?
Say, I don't want a program to run longer than 5 hours.. How would that be
implemented?

--Aldric
There are various methods for real time computing. It really depends on how
exact you want to be.
 
G

Glen Holcomb

[Note: parts of this message were removed to make it a legal post.]

There are various methods for real time computing. It really depends on
how exact you want to be.

--
"Hey brother Christian with your high and mighty errand, Your actions speak
so loud, I can't hear a word you're saying."

-Greg Graffin (Bad Religion)

Sorry that answer was a bit useless. Here is a very simple example:

You could have two threads, your main thread and a sub-thread. At the
beginning of execution put the sub-thread to sleep for 5 hours (18000
seconds). Then put whatever code you want in the main thread. After 5
hours the sub-thread will wake (assuming there is no blocking I/O or other
impediment). In the sub-thread simply call exit.

This is an insanely simple example though.
 
A

Aldric Giacomoni

I don't need atomic precision - I need to stop a task that runs
overnight (being 5 minutes off would not be a problem) so that it's not
still running when a user gets to their machine.
I did a search on 'real-time computing' but got nothing relevant to me -
maybe I did the search wrong.. ?

Glen said:
[Note: parts of this message were removed to make it a legal post.]

Any idea how to do that?
Say, I don't want a program to run longer than 5 hours.. How would that be
implemented?

--Aldric
There are various methods for real time computing. It really depends on how
exact you want to be.
 
G

Glen Holcomb

[Note: parts of this message were removed to make it a legal post.]

I don't need atomic precision - I need to stop a task that runs overnight
(being 5 minutes off would not be a problem) so that it's not still running
when a user gets to their machine.
I did a search on 'real-time computing' but got nothing relevant to me -
maybe I did the search wrong.. ?

Glen said:
[Note: parts of this message were removed to make it a legal post.]

Any idea how to do that?
Say, I don't want a program to run longer than 5 hours.. How would that
be
implemented?

--Aldric


There are various methods for real time computing. It really depends on
how
exact you want to be.
If there is a chance that your process will be blocking for whatever reason
you could always write one script that launches the other process and after
5 hours looks for the process it started and kills it then exits. That
isn't super clean but would work.
 
A

Aldric Giacomoni

Glen said:
You could have two threads, your main thread and a sub-thread. At the
beginning of execution put the sub-thread to sleep for 5 hours (18000
seconds). Then put whatever code you want in the main thread. After 5
hours the sub-thread will wake (assuming there is no blocking I/O or other
impediment). In the sub-thread simply call exit.

This is an insanely simple example though.

I think .. Your simple example actually fits my needs :)

Thanks for the help and the various hints about thinking in threads.
 
R

Robert Dober

Maybe you should look for the timeout tool on the Web. There is a
somehow old association between timeout and Ara in my brain.

HTH
R.
 
R

Rob Biedenharn

require 'timeout'

HOURS = 60 * 60 # seconds, minutes
time_limit = 5 * HOURS

begin
Timeout.timeout(time_limit) do
# your program goes here
end
rescue Timeout::Error
puts "Program has exceeded allotted time, exiting."
end

--
Avdi

Home: http://avdi.org
Developer Blog: http://avdi.org/devblog/
Twitter: http://twitter.com/avdi
Journal: http://avdi.livejournal.com


In particular, this can't interrupt system calls and can even be
foiled by something as "simple" as a nasty, poorly-written,
backtracking regexp that will eventually complete, but might consume
resources for several more hours. (This one bit me once, can you
tell? ;-)

-Rob

Rob Biedenharn http://agileconsultingllc.com
(e-mail address removed)
 
J

Jos Backus

Fwiw, coreutils 7.0 will have a `timeout' program; it runs a command with
bounded time.
 
R

Ron Fox

See http://www.ruby-doc.org/core-1.9/classes/Process.html#M003012

It and sleep have all the tools you need to do this. The idea is that
you have a master process that forks the child process which runs the
script you want to time. The master process then loops. The loop
sleeps a bit then calls waitpid with the WNOHANG flag to see if the
child has exited. Count the sleep time, or use Time to figure out how
long you've been waiting.. Once you've waited long enough, use kill
to kill the child process. If the child has exited.. the master
process exits.

The length of your sleep in the loop of the master process determines
- The precision with which you measure the timeout.
- The latency with which the master process responds to normal child exit.

Ron.
 
R

Robert Klemme

2008/12/4 Aldric Giacomoni said:
I don't need atomic precision - I need to stop a task that runs overnight
(being 5 minutes off would not be a problem) so that it's not still running
when a user gets to their machine.

If you start your job via crontab another reasonably simple approach
would be to store the PID in a file on startup and schedule another
script 5 hours later that simply sends a kill -INT (or whatever). The
you can handle the signal in your main script and do whatever you need
to to to clean up and exit.

Kind regards

robert
 
A

Aldric Giacomoni

Everybody automatically assumes that rubyists are using Linux - sadly,
in the medical field Linux is not an option unless you're working with
the modality itself. Medical software is almost all Windows-based.. So,
Windows is where I am for this issue and Windows is where I remain :(
If it were for an outside-Ruby solution, I can think of tons of options.
I just want a program which works and does everything all by itself..
Because if I have to deploy this to 400 machines, I don't wanna have to
do any more setup work than absolutely required.
 
G

Glen Holcomb

[Note: parts of this message were removed to make it a legal post.]

Everybody automatically assumes that rubyists are using Linux - sadly, in
the medical field Linux is not an option unless you're working with the
modality itself. Medical software is almost all Windows-based.. So, Windows
is where I am for this issue and Windows is where I remain :(
If it were for an outside-Ruby solution, I can think of tons of options. I
just want a program which works and does everything all by itself.. Because
if I have to deploy this to 400 machines, I don't wanna have to do any more
setup work than absolutely required.
I'm in the same boat here at work. Fork won't work in Windows so that
option is out. However if the thread or timeout suggestions don't work for
you it might be possible to adjust Robert's suggestion to run as a Windows
Task. I don't know if you can put a time limit on a task though (don't use
them very often).
 
G

Glen Holcomb

[Note: parts of this message were removed to make it a legal post.]

I'm in the same boat here at work. Fork won't work in Windows so that
option is out. However if the thread or timeout suggestions don't work for
you it might be possible to adjust Robert's suggestion to run as a Windows
Task. I don't know if you can put a time limit on a task though (don't use
them very often).

--
"Hey brother Christian with your high and mighty errand, Your actions speak
so loud, I can't hear a word you're saying."

-Greg Graffin (Bad Religion)

Another option (to expand on my second suggestion) would be to compile the
potentially long running script into an exe using rubyscript2exe and then
launch it from another script system("start script.exe") then after five
hours wake up and check the windows process list for script.exe and if it is
running kill it:

wmi =
WIN32OLE.connect("winmgmts:{impersonationLevel=impersonate,(Shutdown)}\\\\#{name}\\root\\cimv2")
proc_list = wmi.ExecQuery("select * from win32_process")
proc_list.each do |process|
if process.Name == "script.exe"
process.Terminate(8)
end
end

http://msdn.microsoft.com/en-us/library/aa394372(VS.85).aspx

You would of course need to require 'win32ole' for this to work.
 
G

Glen Holcomb

[Note: parts of this message were removed to make it a legal post.]

Another option (to expand on my second suggestion) would be to compile the
potentially long running script into an exe using rubyscript2exe and then
launch it from another script system("start script.exe") then after five
hours wake up and check the windows process list for script.exe and if it is
running kill it:

wmi =
WIN32OLE.connect("winmgmts:{impersonationLevel=impersonate,(Shutdown)}\\\\#{name}\\root\\cimv2")
proc_list = wmi.ExecQuery("select * from win32_process")
proc_list.each do |process|
if process.Name == "script.exe"
process.Terminate(8)
end
end

http://msdn.microsoft.com/en-us/library/aa394372(VS.85).aspx<http://msdn.microsoft.com/en-us/library/aa394372(VS.85).aspx>

You would of course need to require 'win32ole' for this to work.


--
"Hey brother Christian with your high and mighty errand, Your actions speak
so loud, I can't hear a word you're saying."

-Greg Graffin (Bad Religion)

Sorry copied that from another program of mine without looking at it too
closely. You don't need to impersonate on the WIN32OLE.connect and #{name}
should be the machine hostname so something like this should work:

require 'socket'
require 'win32ole'

wmi = WIN32OLE.connect("winmgmts:\\\\#{Socket.hostname}\\root\\cimv2")
proc_list = wmi.ExecQuery("select * from win32_process")
proc_list.each do |process|
if process.Name == "script.exe"
process.Terminate(8)
end
end
 
G

Glen Holcomb

[Note: parts of this message were removed to make it a legal post.]

Sorry copied that from another program of mine without looking at it too
closely. You don't need to impersonate on the WIN32OLE.connect and #{name}
should be the machine hostname so something like this should work:

require 'socket'
require 'win32ole'

wmi = WIN32OLE.connect("winmgmts:\\\\#{Socket.hostname}\\root\\cimv2")
proc_list = wmi.ExecQuery("select * from win32_process")
proc_list.each do |process|
if process.Name == "script.exe"
process.Terminate(8)
end
end

--
"Hey brother Christian with your high and mighty errand, Your actions speak
so loud, I can't hear a word you're saying."

-Greg Graffin (Bad Religion)

Yet another typo, I really shouldn't do this until I'm awake.

#{Socket.hostname} should actually be #{Socket.gethostname}
 
R

Robert Klemme

2008/12/5 Glen Holcomb said:
However if the thread or timeout suggestions don't work for
you it might be possible to adjust Robert's suggestion to run as a Windows
Task. I don't know if you can put a time limit on a task though (don't use
them very often).

I believe Windows has also a scheduling service. So you could use
that instead of cron.

Cheers

robert
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top