From: ken yip
Subject: Running a process with fixed time allocation (lucid)
Date: 
Message-ID: <1c41q0INNgkp@AUSTRALIA.AI.CS.YALE.EDU>
How could one create a process (make-process) that would run for a fixed amount
of time?  I don't want this subprocess to worry about how much time it has
though.

From: Len Charest
Subject: Re: Running a process with fixed time allocation (lucid)
Date: 
Message-ID: <1992Oct21.214203.21156@jpl-devvax.jpl.nasa.gov>
In article <············@AUSTRALIA.AI.CS.YALE.EDU>, ·······@cs.yale.edu (ken yip) writes:
|> How could one create a process (make-process) that would run for a fixed amount
|> of time?  I don't want this subprocess to worry about how much time it has
|> though.

There are several ways to do this using CL's built-in time functions (specif.
GET-INTERNAL-RUN-TIME) and/or Lucid's multitasking functions (e.g.,
PROCESS-WAIT-WITH-TIMEOUT). The correct solution depends largely on the nature of
the computation you are doing in the fixed-time process. Can you safely interrupt
the computation at any time? Do you want to be able to continue the computation
after its allocated run time has expired?

Here's an example of a process that introspectively checks the amount of time it
has used in the CPU. The process dies 'naturally' (via the scheduler) when its
time is up.

;;; time-limit expressed as seconds
(defun make-self-conscious-process (time-limit)
  (make-process
   :name "Self Conscious"
   :function #'(lambda (stream time-limit)
		 (loop with start = (get-internal-run-time)
		       and delta
		       initially (format stream "~&Starting ~s at ~d.~%"
					 *current-process*
					 start)
		       do (setq delta (- (get-internal-run-time) start))
		       while (< delta time-limit)
		       do (format stream "~5,2f "
				  (/ delta time-limit))
		       finally (format stream "~&Finished ~s at ~d."
				       *current-process*
				       (+ start delta))))
   :args (list *standard-output*
	       (* time-limit internal-time-units-per-second))))

Sample run (I reformatted some of the output):

> *all-processes*
(#<Process Initial A02926> #<Process Idle A02986>)
> (make-self-conscious-process .5)
#<Process Self Conscious 1D2BABE>
> 
Starting #<Process Self Conscious 1D2BABE> at 59040000.
0.00  0.00  0.02  0.02  0.02  0.04  0.04  0.04  0.06  0.06  0.06  0.10  
0.12  0.12  0.12  0.12  0.14  0.14  0.16  0.16  0.16  0.18  0.18  0.18  
0.20  0.20  0.22  0.22  0.22  0.24  0.24  0.26  0.26  0.28  0.30  0.30  
0.30  0.32  0.32  0.34  0.34  0.34  0.36  0.36  0.38  0.38  0.38  0.40  
0.40  0.40  0.42  0.42  0.44  0.44  0.44  0.46  0.46  0.48  0.48  0.48 
0.50  0.50  0.50  0.50  0.56  0.56  0.56  0.58  0.60  0.60  0.62  0.62  
0.64  0.64  0.64  0.66  0.66  0.66  0.68  0.68  0.70  0.70  0.70  0.72  
0.72  0.72  0.74  0.74  0.76  0.76  0.76  0.78  0.78  0.80  0.82  0.82  
0.82  0.84  0.84  0.86  0.86  0.86  0.88  0.88  0.90  0.90  0.92  0.92  
0.94  0.94  0.94  0.96  0.96  0.98  0.98  0.98 
Finished #<Process Self Conscious 1D2BABE> at 59540000.
> *all-processes*
(#<Process Initial A02926> #<Process Idle A02986>)

Here's another example wherein 2 processes are created: the 'slave' process does
the actual computation while the 'master' process watches the clock. When the
slave's time-limit is reached the master kills the slave.

(defun toil ()
  (loop))

;;; time-limit expressed as seconds
(defun make-master/slave-processes (time-limit)
  (let* ((slave (make-process
		 :name "Slave"
		 :function #'toil))
	 (master (make-process
		  :name "Master"
		  :function #'(lambda (stream nsec)
				(process-wait-with-timeout "Waiting" nsec #'ignore)
				(format stream "~&~s killing ~s."
					*current-process* slave)
				(kill-process slave))
		  :args (list *standard-output* time-limit))))
    (values master slave)))

Sample run:

> *all-processes*
(#<Process Initial A02926> #<Process Idle A02986>)
> (make-master/slave-processes 10)
#<Process Master 1D3B8AE>
#<Process Slave 1D3B7D6>
> *all-processes*
(#<Process Master 1D3B8AE> #<Process Slave 1D3B7D6> #<Process Initial A02926> #<Process Idle A02986>)
> 
#<Process Master 1D3B8AE> killing #<Process Slave 1D3B7D6>.
> *all-processes*
(#<Process Initial A02926> #<Process Idle A02986>)

..................................................
                                  Len Charest, Jr.
                 JPL Artificial Intelligence Group
                          ·······@aig.jpl.nasa.gov
From: Eskil Brun
Subject: Re: Running a process with fixed time allocation (lucid)
Date: 
Message-ID: <eskilb.719869193@fenris.dhhalden.no>
·······@cs.yale.edu (ken yip) writes:


>How could one create a process (make-process) that would run for a fixed amount
>of time?  I don't want this subprocess to worry about how much time it has
>though.

Create a watchdog process that does a process-wait-with-timeout.
Make it interrupt-process (other-process) with a throw to an outer
catch. I'm sorry I can't give you more specific details - I really
hate this News interface ;-)

Cheers,
Eyvind.

Eyvind Ness, Research Scientist @ OECD HRP, ······@hrp.no