#fork and deterministic resumption of the resulting process
Mathieu Suen
mathk.sue at gmail.com
Mon Feb 4 21:41:01 UTC 2008
Hi,
On Feb 4, 2008, at 10:04 PM, Andreas Raab wrote:
> Hi -
>
> In my never-ending quest for questionable behavior in multi-threaded
> situations just today I ran into a pattern which is dangerously
> common in our code. It basically goes like this:
>
> MyClass>>startWorkerProcess
> "worker is an instance variable"
> worker:= [self runWorkerProcess] fork.
>
Why don't you make the assignment atomic?
> MyClass>>runWorkerProcess
> "Run the worker process"
> [Processor activeProcess == worker] whileTrue:[
> "...do the work..."
> ].
>
> MyClass>>stopWorkerProcess
> "Stop the worker process"
> worker := nil. "let it terminate itself"
>
> Those of you who can immediately tell what the problem is should get
> a medal for an outstanding knack of analyzing concurrency problems ;-)
>
> For the rest of us, the problem is that #fork in the above is not
> deterministic in the way that there is no guarantee whether the
> "worker" variable will be assigned when we enter the worker loop. It
> *would* be deterministic if the priority were below or above the
> current process' priority but when it's the same it can be affected
> by environmental effects (external signals, delay processing etc)
> leading to some very obscure runtime problems (in the above, the
> process would just not start).
>
> To fix this problem I have changed BlockContext>>fork and
> BlockContext>>forkAt: to read, e.g.,
>
> BlockContext>>fork
> "Create and schedule a Process running the code in the receiver."
> ^self forkAt: Processor activePriority
>
> BlockContext>>forkAt: priority
> "Create and schedule a Process running the code in the receiver
> at the given priority. Answer the newly created process."
> | forkedProcess helperProcess |
> forkedProcess := self newProcess.
> forkedProcess priority: priority.
> priority = Processor activePriority ifTrue:[
> helperProcess := [forkedProcess resume] newProcess.
> helperProcess priority: priority-1.
> helperProcess resume.
> ] ifFalse:[
> forkedProcess resume
> ].
> ^forkedProcess
>
> This will make sure that #fork has (for the purpose of resumption)
> the same semantics as forking at a lower priority has.
>
> What do people think about this?
>
> Cheers,
> - Andreas
>
Mth
More information about the Squeak-dev
mailing list
|