#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