Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How to automatically kill a function call after a long-time run?

191 views
Skip to first unread message

Lei Tang

unread,
Sep 19, 2006, 4:40:03 PM9/19/06
to
Hi, everyone.

I want to write some code to run some test cases by calling some
functions(suppose "A"). However, "A" might take extremely long time if
it doesn't do it efficiently. So I hope that my test-case code can
automatically terminate the function call of A if it doesn't give me the
result after some time (eg. 2 hours), so that I can check another test
case. Is there any way to do this in lisp? I really appreciate your help!!

-Lei

Pascal Bourguignon

unread,
Sep 19, 2006, 5:04:52 PM9/19/06
to
Lei Tang <L.T...@asu.edu> writes:

[41]> (with-timeout (5 (print :timed-out))
(loop :repeat 3
:do (sleep 1) (princ ".") (finish-output)
:finally (return :done)))
...
:DONE
[42]> (with-timeout (5 (print :timed-out))
(loop :repeat 10
:do (sleep 1) (princ ".") (finish-output)
:finally (return :done)))
....
:TIMED-OUT
:TIMED-OUT
[43]>

;;;;**************************************************************************
;;;;FILE: clisp--with-timeout.lisp
;;;;LANGUAGE: Common-Lisp
;;;;SYSTEM: Common-Lisp
;;;;USER-INTERFACE: NONE
;;;;DESCRIPTION
;;;;
;;;; Testing SIGALRM on clisp on Linux.
;;;;
;;;;AUTHORS
;;;; <PJB> Pascal Bourguignon <p...@informatimago.com>
;;;;MODIFICATIONS
;;;; 2006-05-02 <PJB> Added this header.
;;;;BUGS
;;;;LEGAL
;;;; GPL
;;;;
;;;; Copyright Pascal Bourguignon 2006 - 2006
;;;;
;;;; This program is free software; you can redistribute it and/or
;;;; modify it under the terms of the GNU General Public License
;;;; as published by the Free Software Foundation; either version
;;;; 2 of the License, or (at your option) any later version.
;;;;
;;;; This program is distributed in the hope that it will be
;;;; useful, but WITHOUT ANY WARRANTY; without even the implied
;;;; warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
;;;; PURPOSE. See the GNU General Public License for more details.
;;;;
;;;; You should have received a copy of the GNU General Public
;;;; License along with this program; if not, write to the Free
;;;; Software Foundation, Inc., 59 Temple Place, Suite 330,
;;;; Boston, MA 02111-1307 USA
;;;;**************************************************************************
;;;;

(defun install-signal-handler (signum handler)
(let ((oldhan (linux:|set-signal-handler| signum handler))
(sigset (second (multiple-value-list
(linux:|sigaddset| (second (multiple-value-list
(linux:|sigemptyset|)))
signum)))))
(linux:|sigprocmask-set-n-save| linux:|SIG_UNBLOCK| sigset)
(values signum oldhan sigset)))


(defun restore-signal-handler (signum oldhan sigset)
(linux:|set-signal-handler| signum oldhan)
(linux:|sigprocmask-set-n-save| linux:|SIG_UNBLOCK| sigset))

(defmacro with-signal-handler (signum handler &body body)
(let ((voldhan (gensym))
(vsignum (gensym))
(vsigset (gensym)))
`(let* ((,vsignum ,signum)
(,voldhan (linux:|set-signal-handler| ,vsignum ,handler))
(,vsigset (second (multiple-value-list
(linux:|sigaddset|
(second (multiple-value-list
(linux:|sigemptyset|)))
,vsignum)))))
(linux:|sigprocmask-set-n-save| linux:|SIG_UNBLOCK| ,vsigset)
(unwind-protect (progn ,@body)
(linux:|set-signal-handler| ,vsignum ,voldhan)
(linux:|sigprocmask-set-n-save| linux:|SIG_UNBLOCK| ,vsigset)))))


(defmacro with-sigseg-handler (&body body)
`(with-signal-handler linux:|SIGSEGV|
(lambda (signum)
(declare (ignore signum))
(error "Got Segment Violation Signal while accessing raw memory"))
,@body))


(defmacro with-timeout ((seconds &body timeout-forms) &body body)
"
This macro evaluates the body as a progn body. If the evaluation
of body does not complete within the specified interval, execution
throws out of the body and the timeout-forms are evaluated as a
progn body, returning the result of the last form.) The
timeout-forms are not evaluated if the body completes within
seconds.
"
(let ((timeout (gensym)))
`(block ,timeout
(with-signal-handler linux:|SIGALRM|
(lambda (signum)
(declare (ignore signum))
(return-from ,timeout (progn ,@timeout-forms)))
(LINUX:alarm ,seconds)
(unwind-protect (progn ,@body)
(LINUX:alarm 0))))))


;; Note: man 2 alarm warns against using sleep(2) and SIGALRM at the same time.
;; Happily, it seems that on Linux they can be used together.


;; Local Variables:
;; eval: (cl-indent 'with-signal-handler 2)
;; End:

--
__Pascal Bourguignon__ http://www.informatimago.com/

READ THIS BEFORE OPENING PACKAGE: According to certain suggested
versions of the Grand Unified Theory, the primary particles
constituting this product may decay to nothingness within the next
four hundred million years.

John Stoneham

unread,
Sep 19, 2006, 5:52:41 PM9/19/06
to
I've had to do this in my current project. For a simple,
quick-and-dirty solution, at the start of your main computation loop
just set up a START-TIME variable with GET-UNIVERSAL-TIME, and update a
CURR-TIME variable with another call to GET-UNIVERSAL-TIME on each
iteration, and exit the loop when (>= (- curr-time start-time)
max-seconds).

Sort of like this:

(defun run-long (max-seconds)
(do* ((start-time (get-universal-time))
(curr-time (start-time) (get-universal-time)))
((>= (- curr-time start-time) max-seconds))
( ... stuff here ... )))

For a 2 hour cutoff, call with (run-long 7200).

For a more complete solution, look over Pascal's code.

Lei Tang

unread,
Sep 20, 2006, 7:33:22 PM9/20/06
to
Thanks a lot for your solution. But how to change it to a windows
version? I tried to replace the "linux" with "windows" seems not work.

-Lei

Pascal Bourguignon

unread,
Sep 20, 2006, 9:14:34 PM9/20/06
to
Lei Tang <L.T...@asu.edu> writes:

> Thanks a lot for your solution. But how to change it to a windows
> version? I tried to replace the "linux" with "windows" seems not work.

I don't know. I know nothing about MS-Windows.

You'd have to learn about MS-Windows. I hear Microsoft has a nice web
site gathering all the developer documentation about MS-Windows.

Then you could write FFI declarations in clisp to call MS-Windows
functions to implement the similar functionalities. If you feel
generous, you could even contribute to clisp a MS-WINDOWS module
similar to the LINUX module ;-)

--
__Pascal Bourguignon__ http://www.informatimago.com/

Pour moi, la grande question n'a jamais été: «Qui suis-je? Où vais-je?»
comme l'a formulé si adroitement notre ami Pascal, mais plutôt:
«Comment vais-je m'en tirer?» -- Jean Yanne

Lei Tang

unread,
Sep 20, 2006, 11:46:40 PM9/20/06
to
I am considering whether or not to switch to Linux:)
Seems windows is not a good choice for xemacs and lisp.

-Lei

Pascal Bourguignon

unread,
Sep 21, 2006, 12:17:49 AM9/21/06
to
Lei Tang <L.T...@asu.edu> writes:
> Pascal Bourguignon wrote:
>> Lei Tang <L.T...@asu.edu> writes:
>>
>>>Thanks a lot for your solution. But how to change it to a windows
>>>version? I tried to replace the "linux" with "windows" seems not work.
>> I don't know. I know nothing about MS-Windows.
>> You'd have to learn about MS-Windows. I hear Microsoft has a nice
>> web
>> site gathering all the developer documentation about MS-Windows.
>> Then you could write FFI declarations in clisp to call MS-Windows
>> functions to implement the similar functionalities. If you feel
>> generous, you could even contribute to clisp a MS-WINDOWS module
>> similar to the LINUX module ;-)
>
> I am considering whether or not to switch to Linux:)
> Seems windows is not a good choice for xemacs and lisp.

At the same time you might consider switching to bottom posting too.


--
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
----------> http://www.netmeister.org/news/learn2quote.html <-----------
---> http://homepage.ntlworld.com/g.mccaughan/g/remarks/uquote.html <---

__Pascal Bourguignon__ http://www.informatimago.com/

John Thingstad

unread,
Sep 21, 2006, 1:51:42 AM9/21/06
to

xemacs is never a good choice use emacs.
As for Windows and Lisp the comecial versions are ok.
ACL rules if you can afford it.
Unix belongs in a museum :)

--
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/

Jock Cooper

unread,
Sep 25, 2006, 2:07:06 PM9/25/06
to
Lei Tang <L.T...@asu.edu> writes:

You could use the multiprocessing package and run the function as a
process. Then the main process could kill the process if it runs too
long. However it isn't really safe to kill a process that way (for
example, if the kill occurs while the process is processing unwind
forms).

I have found it is safest have the to function cooperate by
terminating itself. Your processes can communicate using structures
such as MP:QUEUE and MP:GATE (ACL has these, not sure if other CLs
do). And of course judicious use of macros can make this scheme as
unobtrusive as needed.

0 new messages