Hi all,
I have a proposal and I’d like to hear your opinion. Right now, when I want to wait for a process to finish I use something like #forkAndWait or I write a block with semaphores myself. This works fine for processes that I spawn and then immediately want to wait for. But what if I spawn a process somewhere else and only later know that I want to wait for its termination? Currently I would construct a polling loop to do that. Here’s a different idea (which I’ve tested): 1. add instance variable “terminationSemaphore” to Process 2. at the end of Process>>terminate #ensure: that all waiting processes are signaled 3. add #waitForTermination message to Process: waitForTermination terminationSemaphore ifNil: [ terminationSemaphore := Semaphore new ]. self resume. terminationSemaphore wait This enables code like the following: result := 0. p := [ result := 2. 2 seconds asDelay wait ] newProcess priority: 20; yourself. “don’t run the new process yet" [ p waitForTermination. result2 := 3. ] forkAt: 30. “p is now running, the second process is waiting" p waitForTermination. “p is still running, two processes are waiting” “because processes waiting on a semaphore are signaled in the order they sent #wait we even achieve ordering (at least with equal process priorities) and so ‘result2’ is not nil but 3” {result. result2} “#(2 3) I wrote this in 10 minutes, so there’s room for polishing. I just want to know if this is something other people might want and if there are potential problems with process termination and semaphores which I am not aware of. Cheers, Max |
Hi Max,
On Fri, Feb 12, 2016 at 6:59 AM, Max Leske <[hidden email]> wrote:
Seems very nice. But why not add both terminationSemaphore and result? So we have Process class methods for instance creation forBlock: aBlockClosure priority: anInteger "Answer an instance of me that has suspended aContext at priority anInteger." <primitive: 19> "Simulation guard" | newProcess | (newProcess := self new) suspendedContext: [newProcess result: aBlockClosure value. newProcess terminationSemaphore ifNotNil: [:ts| ts signal]. "Since control is now at the bottom there is no need to terminate (which runs unwinds) since all unwinds have been run. Simply suspend. Note that we must use this form rather than e.g. Processor suspendActive so that isTerminated answers true. isTerminated requires that if there is a suspended context it is the bottom-most, but using a send would result in the process's suspendedContext /not/ being the bottom-most." newProcess suspend] asContext; priority: anInteger. ^newProcess BlockClosure methods for scheduling newProcess "Answer a Process running the code in the receiver. The process is not scheduled." ^Process forBlock: self priority: Processor activePriority Process methods for termination waitForTermination terminationSemaphore ifNil: [ terminationSemaphore := Semaphore new ]. self resume. terminationSemaphore wait. ^result ((1 to: 3) collect: [:i| [(Delay forSeconds: i) wait. i] forkAt: Processor activePriority - 1]) collect: [:p| p waitForTermination] #(1 2 3) [find attached, leaving BlockClosure>>newProcessWith: as an exercise for the reader ;-) ] _,,,^..^,,,_ best, Eliot waitForTermination.st (2K) Download Attachment |
Thanks Eliot.
Nice idea to return the result. What didn’t work for me was to only suspend the process in #forBlock:priority:. I had to send #terminate instead. There are two main reasons: 1. #isTerminating (not #isTerminated) will not be correctly set if #terminate hasn’t been sent 2. when signalling the semaphore I want *all* processes that are waiting to be signalled so that the terminating process can’t be preempted while signalling the semaphore. Otherwise it may resume a higher priority process that will not allow the other processes still waiting on the semaphore to run. To do this I have to use different approaches for active and inactive processes, such that #isTerminated is always true when the termination semaphore has been signalled. I’d appreciate it if you could take a look. Maybe you’ll spot something I could have done better. Cheers, Max
Kernel-MaxLeske.2227.cs (22K) Download Attachment |
Free forum by Nabble | Edit this page |